2

我正在尝试定义实体架构,如果简化,可以这样表示:

class M(models.Model):
    field_m = models.CharField(max_length=255)
    class Meta:
        abstract = True

class A(M):
    field_a_1 = models.CharField(max_length=255)
    field_a_2 = models.CharField(max_length=255)
    class Meta:
        abstract = True

class B(A):
    field_b = models.CharField(max_length=255)
    class Meta:
        abstract = True

class C(A):
    field_c = models.CharField(max_length=255)
    class Meta:
        abstract = True


class D(A):
    field_d = models.CharField(max_length=255)
    class Meta:
        abstract = True

class DD(D):
    class Meta:
        abstract = True

class X(B, C, DD):
    field_x = models.CharField(max_length=255)
    pass

如您所见,X有一些混入(抽象实体)。每个 mixin 都在其中实现了自己的自定义逻辑。但最终它们都有一个共同的父摘要class A

据我了解,这应该有效。MRO 解决方案确实有效。但是,在启动项目时,每个字段字段A(在 中继承X)出现 2 个错误:

X.field_m : (models.E006) The field 'field_m ' clashes with the field 'field_m ' from model 'X'.
X.field_m : (models.E006) The field 'field_m ' clashes with the field 'field_m ' from model 'X'.
X.field_a_1 : (models.E006) The field 'field_a_1 ' clashes with the field 'field_a_1 ' from model 'X'.
X.field_a_1 : (models.E006) The field 'field_a_1 ' clashes with the field 'field_a_1 ' from model 'X'.
X.field_a_2 : (models.E006) The field 'field_a_2 ' clashes with the field 'field_a_2 ' from model 'X'.
X.field_a_2 : (models.E006) The field 'field_a_2 ' clashes with the field 'field_a_2 ' from model 'X'.

我正在使用 Django 1.11

4

1 回答 1

2

这里有一个旧问题单,导致 Django 验证这些问题 https://code.djangoproject.com/ticket/24542

这是因为 B 和 C 从 A 继承,所以它们将具有相同的field_m并且无效。Django 开发人员决定 Django 将验证这一点,而不是

忽略与现有字段同名的抽象模型基类(按 MRO 顺序)中的后续模型字段。

在旁注中。这是一个糟糕的设计,您应该按照文档https://docs.djangoproject.com/en/2.2/topics/db/models/#s-multiple-inheritance保持继承简单

通常,您不需要从多个父母那里继承。这很有用的主要用例是“混入”类:向每个继承混入的类添加特定的额外字段或方法。尽量使继承层次结构尽可能简单明了,这样您就不必费力找出特定信息的来源。

于 2019-08-29T09:03:27.113 回答