如何让两个模型相互引用 Django

Posted

技术标签:

【中文标题】如何让两个模型相互引用 Django【英文标题】:How to have two models reference each other Django 【发布时间】:2012-12-08 08:19:33 【问题描述】:

我有以下代码:

class Game(models.Model):
    title = models.CharField(max_length=50)
    summery = models.CharField(max_length=500)
    key = models.IntegerField()
    pin = models.CharField(max_length=12)
    complete = models.BooleanField()
    invite_sent = models.DateTimeField()
    on = models.ForeignKey(Member, blank = True) #<----


class Member(models.Model):
    email = models.CharField(max_length=100)
    color = models.CharField(max_length=11)
    game = models.ForeignKey(Game) #<----

“on”外键链接到其中一个成员(轮到谁)。游戏的所有成员都将他们的“游戏”外键设置为他们所在的游戏。问题是Django不允许我在声明之前引用一个类,因为我不能同时声明它们......

编辑:为了清楚起见,这里有一个例子。如果有五个成员玩一个游戏,那么所有五个成员都将拥有该游戏的外键。另一方面,游戏对于轮到它的特定成员有一个外键。

【问题讨论】:

这里可能不合适,但一般来说,您可以通过将类的名称作为字符串而不是类本身传递来为尚未声明的类创建 ForeignKey。跨度> 【参考方案1】:

您不需要让两个模型使用外键相互引用。删除该行:

on = models.ForeignKey(Member, blank = True) #<----

从逻辑上讲,您的Member 仍将与不同的Game 相关联(这更有意义,因为一个成员一次可以属于一个游戏,而一个游戏可以有多个成员) .

您可以使用reverse relation 来确定特定游戏中有哪些成员。

【讨论】:

我可能没有把我的情况说清楚(或者我不明白你的答案)。如果你有 5 个成员都玩一个游戏,那么他们都会引用同一个游戏。但是“on”外键只会引用轮到它的人(单个成员)。【参考方案2】:

Django documentation for the ForeignKey field 声明:

如果您需要在尚未定义的模型上创建关系,您可以使用模型的名称,而不是模型对象本身。

所以在你的情况下,那就是:

class Game(models.Model):
    # Other fields...
    on = models.ForeignKey('Member', blank = True)

class Member(models.Model):
    # Other fields...
    game = models.ForeignKey(Game)

【讨论】:

对我来说,在ForeignKeyOneToOneFieldManyToManyField 中经常使用'app.model' 符号是非常好的做法。我已经使用它来将模型文件拆分为每个模型一个文件,这样更具可读性。 @SteveK 这帮助我解决了循环导入问题,谢谢! 在给定null=False 默认参数的情况下,您将如何保存这种关系? 感谢您的回答!我只是想知道,这是一种好的做法还是正常的做法,还是一种 hack? 如果那个模型不能保持空白怎么办?

以上是关于如何让两个模型相互引用 Django的主要内容,如果未能解决你的问题,请参考以下文章

django:如何从包含外键的多个模型中制作一个表单

使用实体框架,如何在两个模型上添加外键以相互引用

在 Django 中,如何让模型引用自身?

删除 2 个作为外键相互引用的模型不同对象

Django模型:如何避免在使用来自同一个表的2个外键时引用相同的记录

Django自引用多对多模型