Django:为什么有些模型领域彼此冲突?

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

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

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

  • 字段“目标”的访问者与相关字段“User.gameclaim_set”发生冲突。 将“related_name”参数添加到“target”的定义中。

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

你能解释为什么我得到的错误,以及如何解决它们?

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

在FK定义中使用related_name属性。 例如

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

User模型试图创build两个同名的字段,一个GameClaimsUsertargetGameClaims ,另一个GameClaimsUserGameClaims 。 这里是related_name的文档 ,这是Django让你设置属性名称的方式,所以自动生成的属性不会发生冲突。

OP不使用抽象基类…但是如果你是的话,你会发现硬编码FK中的related_name(例如…,related_name =“myname”)会导致一些这样的冲突错误 – 每个从基类inheritance的类一个。 下面提供的链接包含解决方法,这很简单,但绝对不明显。

从Django文档…

如果您在ForeignKey或ManyToManyField上使用related_name属性,则必须始终为该字段指定唯一的反向名称。 这通常会导致抽象基类中的问题,因为这个类的字段包含在每个子类中,每次属性(包括related_name)的值完全相同。

更多信息在这里 。

我偶尔遇到这种情况时,我将一个子模块作为一个应用程序添加到一个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会导致所有的数据库表被创build为不正确的名称,所以这似乎是正确的方法。

我遇到这个职位,同时寻找这个问题的解决scheme,所以想法我把这个在这里:)

刚刚添加到约旦的答案(感谢提示约旦),如果您导入应用程序上方的级别,然后导入应用程序,也可能会发生

myproject/ apps/ foo_app/ bar_app/

所以,如果你正在导入应用程序,foo_app和bar_app,那么你可以得到这个问题。 我有apps.INI,所有在settings.INSTALLED_APPS列出的应用程序,foo_app和bar_app

而且你还是要避免导入应用程序,因为这样你就可以在两个不同的命名空间中安装相同的应用程序

apps.foo_appfoo_app

有时你必须在related_name使用额外的格式 – 实际上,在任何时候使用inheritance。

 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会照顾创build唯一的关系名称。

那么在Value类的孩子中,你可以访问:

 herdboard_height_related herdboard_lenght_related herdboard_weight_related 

我有同样的问题。 使用运行python manage.py makemigrations“appname”修复了我。 我不小心删除了一些迁移文件。 不需要重新删除任何文件。