Django继承和父对象相关的名称

时间:2016-10-31 13:32:39

标签: python django inheritance

我正在将项目从django 1.8升级到1.10,看起来django已经改进了对外键和模型继承之间最终名称冲突的检查。 这显然是一件好事,但我需要升级的项目是一个很大的项目,重命名一个模型将是一个地狱。

让我解释一下这个问题:我有一个名为Parent的基类和许多链接在一起的孩子,如下所示:

class Parent(models.Model):
    title = models.CharField(max_length=10)


class ChildA(Parent):
    description = models.TextField()


class ChildB(Parent):
    description = models.TextField()
    childa = models.ForeignKey(ChildA)

这里的冲突是childb对象有2" childa"属性:

  • " childa" ForeignKey的
  • ChildA模型继承的实例(因为childb还具有parent属性)。

这里有两个明显的解决方案:

  • 将ForeignKey ChildB.childa重命名为ChildB.somethingelse
  • ChildA模型重命名为其他内容。

这两种解决方案都花费了很多,并且可能会引入新的错误。 所以我想知道:是否可以重命名继承对象的反向相关名称?

例如:

p = Parent.objects.get(pk=1)
print p.childa_child  # Hit the ChildA instance

我不知道我是否足够清楚,但我会及时更新这个问题。

====编辑====

为了更简洁,如果我有2个模型class Parent(models.Model)class Child(Parent),则会创建动态属性parent.child

是否可以在不触及班级名称的情况下编辑此属性名称?

2 个答案:

答案 0 :(得分:4)

多表继承在基本模型和子类之间创建隐式OneToOneField字段。

Django允许您通过显式设置一对一字段来修改此关系。

class Parent(models.Model):
    title = models.CharField(max_length=10)


class ChildA(Parent):
    parent = models.OneToOneField(to=Parent, parent_link=True)
    description = models.TextField()


class ChildB(Parent):
    parent = models.OneToOneField(to=Parent, parent_link=True)
    description = models.TextField()
    childa = models.ForeignKey(ChildA)

这里重要的一点是parent_link=True参数,它告诉Django使用这个字段声明来管理这两个模型的多表继承。

因此,您现在可以设置related_name='+'以防止Django创建反向关系,或者您可以将related_name设置为更独特的名称:

class ChildA(Parent):
    parent = models.OneToOneField(to=Parent, parent_link=True, related_name='child_a_here')
    description = models.TextField()


class ChildB(Parent):
    parent = models.OneToOneField(to=Parent, parent_link=True, related_name='child_b_here')
    description = models.TextField()
    childa = models.ForeignKey(ChildA)

答案 1 :(得分:0)

我对ChildB如何使用两个ChildA链接感到有点困惑,看起来你可能遗漏了模型中的一些关系字段?无论如何,我认为您正在寻找的是related_name参数。

所以:

class ChildB(Parent):
    description = models.TextField()
    childa = models.ForeignKey(ChildA, related_name='b_children')

你可以这样做一个查询:

a = ChildA.objects.get(id=1)
print(a.b_children)

您可能也对abstract models感兴趣。

相关问题