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

Ole*_*nko 169 python django django-models

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

class GameClaim(models.Model):
    target = models.ForeignKey(User)
    claimer = models.ForeignKey(User)
    isAccepted = models.BooleanField()
Run Code Online (Sandbox Code Playgroud)

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

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

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

你能解释一下为什么我会收到错误以及如何修复它们吗?

Dan*_*man 290

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

使用related_nameFK定义中的属性.例如

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

  • 很好的答案,但我认为你没有成功避免粗鲁:P除非你知道django如何在内部工作,否则"为什么"并不明显. (49认同)
  • 对于刚学习框架的人来说,这并不明显. (13认同)
  • 还应该提到的是,如果您不需要对所有模型使用反向关系.在某些情况下,您可能希望模型关系是单向的.在这种情况下,您使用related_name ='+'.这告诉Django创建单向关系并忽略反向关系. (7认同)
  • 谢谢,错误信息对我来说也不是很明显,但是你对反向关系的解释非常有帮助. (2认同)

Han*_*Gay 8

User模型试图创建具有相同名称的两个领域,一个是GameClaims说有User作为target,而另一个用于GameClaims该有User作为claimer.这是文档related_name,这是Django允许您设置属性名称的方式,因此自动生成的属性不会发生冲突.


Pas*_*nus 7

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

来自django文档......

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

更多信息在这里.