具有多个抽象基类的 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.
我正在尝试定义实体架构,如果简化的话,可以这样表达:
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.