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两个同名的字段,一个GameClaims
该User
为target
的GameClaims
,另一个GameClaims
该User
为GameClaims
。 这里是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_app
和foo_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”修复了我。 我不小心删除了一些迁移文件。 不需要重新删除任何文件。