Django模型中的related_name参数为何不按预期工作?

39 投票
2 回答
20394 浏览
提问于 2025-04-16 15:26

我最近在我的Django模型中遇到了外键冲突的问题。我需要有两个外键(owner和assigned_to),它们最终都指向同一个模型(用户)。

根据我的理解,我需要一个related_name参数来解决这个问题。所以我这样做了:

assigned_to = models.ForeignKey(TaskUser, blank=True, null=True, related_name='user_assignment')

还有

owner = models.ForeignKey(TaskUser, related_name="user_ownership"

但是我仍然遇到了一个错误:

tasks.task: Accessor for field 'owner' clashes with related field 'TaskUser.user
_ownership'. Add a related_name argument to the definition for 'owner'.
tasks.task: Reverse query name for field 'owner' clashes with related field 'TaskUser.user_ownership'. Add a related_name argument to the definition for 'owner'.

为什么我还是会遇到这个错误呢?

有一个情况需要注意,owner是在一个超类(BaseWidget)中,而assigned_to是在一个子类(Task)中。在继承关系中使用related_name会有问题吗?我需要覆盖owner的继承关系,并在子类中重新定义related_name吗?任何帮助都非常感谢!

2 个回答

9

如果你在抽象基类中使用了related_name,那么你需要在里面用到'%(app_label)s'和'%(class)s'这两个占位符。这个内容在Django的文档中有提到。

注意使用related_name时要小心

100

如果你在一个抽象的基类中使用了 ForeignKey 关系,那么所有从这个基类继承的类都会有这个关系。这样一来,你就不能把 related_name 写死,因为所有的子类都会试图在相关的类(这里是 TaskUser)上创建相同的访问器。

你最好这样做:

owner = models.ForeignKey(TaskUser, related_name="%(app_label)s_%(class)s_ownership")

关于这个问题,你可以查看 django 文档

撰写回答