I am trying to define entity architecture that, if simplified, can be expressed like this:
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
As you can see, X
has some mixins (abstract entitites). Each of the mixin has their own custom logic implemented inside them. But ultimately all of them have 1 common parent- abstract class A
.
As far as I understand, this should work. And MRO resolution, indeed, works. However, when starting the project I get 2 errors per each field field A
(that are inherited in X
):
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'.
I am working with Django 1.11
There is an old issue ticket here that resulted in making Django validate these kinds of problems https://code.djangoproject.com/ticket/24542
It is because B and C inherit from A so they will have the same field_m
and it is not valid. Django devs decided that Django will validate this instead of
ignore subsequent model fields from abstract model base classes (per MRO-order) with the same name as existing fields.
On a side note. This is bad design and you should keep your inheritance simple as per the docs 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.