使用继承和ForeignKey时Django syncdb冲突related_name

Posted

技术标签:

【中文标题】使用继承和ForeignKey时Django syncdb冲突related_name【英文标题】:Django syncdb conflicting related_name when using inheritance and ForeignKey 【发布时间】:2011-08-12 09:21:28 【问题描述】:

这一次我认为不是我愚蠢,而是一场真正的冲突。我有以下代码(简化):

from django.db import models

class Alpha(models.Model):
    relation = models.ForeignKey('Delta', related_name = 'reverse_relation', blank = True, null = True)

    class Meta:
        abstract = True

class Beta(Alpha):
    pass

class Gamma(Alpha):
    pass

class Delta(models.Model):
    pass

问题在于 Delta.reverse_relation 可以引用 Beta 实例或 Gamma 实例。我会以某种方式必须提供多个相关名称值(或一个取决于类名的值)。我认为问题很清楚但要完整,错误(运行syncdb时): app.beta:字段“relation”的访问器与相关字段“Delta.reverse_relation”发生冲突。在“关系”的定义中添加一个 related_name 参数。 app.beta:字段“relation”的反向查询名称与相关字段“Delta.reverse_relation”冲突。在“关系”的定义中添加一个 related_name 参数。 app.gamma:字段“relation”的访问器与相关字段“Delta.reverse_relation”发生冲突。在“关系”的定义中添加一个 related_name 参数。 app.gamma:字段“relation”的反向查询名称与相关字段“Delta.reverse_relation”冲突。将related_name 参数添加到“关系”的定义中。

是否有可能将 ForeignKey 放在父 Alpha 中,或者是将这段代码剪切粘贴到 Beta 和 Gamma 的唯一方法?我不喜欢这样做,因为如果我不能在父级中定义所有子级共享的字段的一半,它就会破坏继承点。

非常感谢任何帮助!

(如果有人可以评论为什么错误消息不在代码框中,我会解决这个问题。)

【问题讨论】:

再次通过谷歌找到我自己的问题。发生的事情比我想承认的要多。 【参考方案1】:

我认为您会发现 Django 文档中的以下建议很有帮助且相关: https://docs.djangoproject.com/en/1.7/topics/db/models/#be-careful-with-related-name

基本上将关系字段的声明更改为:

relation = models.ForeignKey('Delta', related_name="%(app_label)s_%(class)s")

祝你好运……

【讨论】:

感谢回复,希望能帮助更多人找到这个解决方案! 如果我有两个具有相同应用标签的外键怎么办?我找不到答案。 related_name 只是一个带有关键字app_labelclass 的模板字符串。如果需要,您可以将第一个 foreign_key 的 related_name 指定为 "%(app_label)s_%(class)s_fk1_set",将第二个指定为 "%(app_label)s_%(class)s_fk2_set"(或您选择的任何其他字符串)

以上是关于使用继承和ForeignKey时Django syncdb冲突related_name的主要内容,如果未能解决你的问题,请参考以下文章

理解 / mySQL 又名欺骗 Django 中的 ForeignKey 关系

Django:扩展用户时,最好使用 OneToOneField(User) 或 ForeignKey(User, unique=True)?

Django 通过 ForeignKey 反向查找

尝试创建 Django 迁移时,ForeignKey 缺少必需的位置参数 on_delete

Django 使用 ForeignKey 形成单元测试

Django 模型继承和外键