【问题标题】:Displaying many-to-many (with through) and self-referencing relationship in Django在 Django 中显示多对多(通过)和自引用关系
【发布时间】:2013-06-18 21:19:31
【问题描述】:

我在 Django 1.5 中设置了一个自引用模型,如下所示:

RELATIONSHIP_PARENT = 1
RELATIONSHIP_BLOCKED = 2
RELATIONSHIP_STATUSES = (
    (RELATIONSHIP_PARENT, 'Parent'),
    (RELATIONSHIP_BLOCKED, 'Blocked'),
) 

class Message(models.Model):
    content = models.CharField("Content", max_length=160, db_index=True)
    relationships = models.ManyToManyField('self',
        through='Relationship',
        symmetrical=False,
        related_name='related_to')

class Relationship(models.Model):
    parent_message = models.ForeignKey(Message, related_name='parent_messages')
    child_message = models.ForeignKey(Message, related_name='child_messages')
    status = models.IntegerField(choices=RELATIONSHIP_STATUSES)

这受到http://charlesleifer.com/blog/self-referencing-many-many-through 帖子的启发,他在其中描述了“不对称关系 - Twitter 模型”(我的目标是在消息之间创建父子关系,但这可能与这个问题无关)。我试图将 Django 管理页面配置为在 Message 部分下显示 Relationship 信息。我尝试遵循我似乎是 Django 文档中最接近的示例,如下所示

from django.contrib import admin
from demo.models import Message, Relationship

class RelationshipInline(admin.TabularInline):
    model = Relationship
    extra = 1

class MessageAdmin(admin.ModelAdmin):
    inlines = (RelationshipInline,)

admin.site.register(Message, MessageAdmin)
admin.site.register(Relationship)

但我收到如下错误:

Exception at /admin/
<class 'demo.models.Relationship'> has more than 1 ForeignKey to <class 'demo.models.Message'>

我知道我的案例与 Django 文档的示例略有不同,因为我有一个自引用模型。我想知道是否有一种方法可以通过管理控制台在一个视图/页面中显示特定消息的关系(比如当前的孩子和父母)。如果是这样,有人可以告诉我怎么做吗?我是 Django 新手,还在学习,如果这个问题太天真,请道歉。谢谢。

【问题讨论】:

标签: django django-models django-admin


【解决方案1】:

正如doc 所说

您的中间模型必须包含一个 - 并且只有一个 - 目标模型的外键(在我们的示例中为 Message)。如果您有多个外键,则会引发验证错误。

【讨论】:

  • 感谢您的回答。 @karthikr 的解决方案有效(显示父消息/关系)。
  • 这不是真的 - 至少现在,您可以在 self 上通过 Many2many,但您必须指定 symmetric = False(我正在阅读您的链接中的文档)
【解决方案2】:

试试这个

class RelationshipInline(admin.TabularInline):
    model = Relationship
    extra = 1
    fk_name = 'parent_message' # or 'child_message' depending on which you want to include

在这种情况下,您需要设置这两个中的哪一个被视为FK

【讨论】:

  • 谢谢@karthikr!这至少可以显示任何消息的子消息。我有一个相关的问题是防止所有可能的子消息显示在管理控制台的下拉列表中。由于我希望在数据库中填充大量消息,因此我不希望 Django 在控制台中将所有可能的选择显示为下拉菜单。这个问题已经在link 讨论过,但是当我在RelationshipInline 中添加raw_id_fields=('parent_message',) 时,它没有..
  • (续)工作。我打算写一篇关于这个的新帖子,但如果你碰巧知道这一点,请告诉我如何防止 Django 管理员在多对多内联显示中将所有可能的选择显示为下拉菜单。谢谢。
  • 您可能正在寻找这个:stackoverflow.com/questions/6581520/… 您基本上是在寻找基于该帖子中介绍的条件过滤查询集
  • 抱歉,你的问题搞错了。已回答。这很可能会起作用
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 2016-04-18
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 2018-04-22
相关资源
最近更新 更多