具有多个抽象基类的 Django 字段类

Django field clash with multiple abstract base clases

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

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 都有自己的内部实现的自定义逻辑。但最终它们都有 1 个共同的父抽象 class A.

据我了解,这应该可行。 MRO 解决方案确实有效。但是,在启动项目时,每个字段 field 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

这里有一张旧问题单导致 Django 验证这些类型的问题 https://code.djangoproject.com/ticket/24542

因为B和C继承自A,所以他们会有相同的field_m,这是无效的。 Django 开发人员决定 Django 将验证它而不是

ignore subsequent model fields from abstract model base classes (per MRO-order) with the same name as existing fields.

旁注。这是糟糕的设计,您应该按照文档 https://docs.djangoproject.com/en/2.2/topics/db/models/#s-multiple-inheritance

保持继承简单

Generally, you won’t need to inherit from multiple parents. The main use-case where this is useful is for “mix-in” classes: adding a particular extra field or method to every class that inherits the mix-in. Try to keep your inheritance hierarchies as simple and straightforward as possible so that you won’t have to struggle to work out where a particular piece of information is coming from.