Django:为什么有些模型字段会相互冲突?

时间:2009-07-17 09:59:09

标签: python django django-models

我想创建一个包含2个用户链接的对象。例如:

class GameClaim(models.Model):
    target = models.ForeignKey(User)
    claimer = models.ForeignKey(User)
    isAccepted = models.BooleanField()

但运行服务器时出现以下错误:

  •   

    字段'target'的访问者与相关字段'User.gameclaim_set'冲突。将related_name参数添加到'target'的定义中。

  •   

    字段'claimer'的访问者与相关字段'User.gameclaim_set'发生冲突。将related_name参数添加到'claimer'的定义中。

您能否解释一下为什么我会收到错误以及如何修复错误?

6 个答案:

答案 0 :(得分:288)

用户有两个外键。 Django自动创建一个从User回到GameClaim的反向关系,通常是gameclaim_set。但是,因为你有两个FK,你将有两个gameclaim_set属性,这显然是不可能的。所以你需要告诉Django反向关系使用什么名称。

使用FK定义中的related_name属性。 e.g。

class GameClaim(models.Model):
    target = models.ForeignKey(User, related_name='gameclaim_targets')
    claimer = models.ForeignKey(User, related_name='gameclaim_users')
    isAccepted = models.BooleanField()

答案 1 :(得分:8)

User模型正在尝试创建两个具有相同名称的字段,一个用于GameClaimsUsertarget,另一个用于{将GameClaims作为User的{​​1}}。这是docs on related_name,这是Django让你设置属性名称的方式,这样自动生成的属性就不会发生冲突。

答案 2 :(得分:7)

OP没有使用抽象基类...但是如果你是,你会发现在FK中对相关名称进行硬编码(例如......,related_name =“myname”)会导致一些这些冲突错误 - 来自基类的每个继承类一个。下面提供的链接包含解决方法,这很简单,但绝对不明显。

来自django docs ......

  

如果您使用的是related_name   ForeignKey或的属性   ManyToManyField,你必须永远   为。指定唯一的反向名称   领域。这通常会导致   抽象基类中的问题,   因为这个类的字段是   包括在每个孩子中   类,具有完全相同的值   对于属性(包括   related_name)每次。

更多信息here

答案 3 :(得分:2)

有时你必须在related_name中使用额外的格式 - 实际上,任何时候使用继承。

class Value(models.Model):
    value = models.DecimalField(decimal_places=2, max_digits=5)
    animal = models.ForeignKey(
        Animal, related_name="%(app_label)s_%(class)s_related")

    class Meta:
        abstract = True

class Height(Value):
    pass

class Weigth(Value):
    pass

class Length(Value):
    pass

此处没有冲突,但related_name定义一次,Django将负责创建唯一的关系名称。

然后在Value类的子级中,您将可以访问:

herdboard_height_related
herdboard_lenght_related
herdboard_weight_related

答案 4 :(得分:0)

当我将一个子模块作为应用程序添加到django项目时,我似乎偶尔会遇到这种情况,例如给出以下结构:

myapp/
myapp/module/
myapp/module/models.py

如果我将以下内容添加到INSTALLED_APPS:

'myapp',
'myapp.module',

Django似乎两次处理myapp.mymodule models.py文件并抛出上述错误。这可以通过不在INSTALLED_APPS列表中包含主模块来解决:

'myapp.module',

包含myapp而不是myapp.module会导致使用错误的名称创建所有数据库表,因此这似乎是正确的方法。

我在寻找这个问题的解决方案时遇到了这个帖子,所以我想把它放在这里:)

答案 5 :(得分:0)

只是添加到Jordan的答案(感谢提示乔丹),如果您导入应用程序上方的级别然后导入应用程序,也会发生这种情况。

myproject/ apps/ foo_app/ bar_app/

因此,如果您要导入应用程序,foo_app和bar_app,那么您可能会遇到此问题。我在settings.INSTALLED_APPS

中列出了所有应用,foo_app和bar_app

你想要避免导入应用程序,因为那时你在2个不同的命名空间中安装了相同的应用程序

apps.foo_appfoo_app