Let’s say I have 2 abstract base classes:
class File(Model):
file = FileField()
size = IntegerField()
mime_type = CharField(max_length=255)
# etc.
class Meta:
abstract = True
constraints = [
CheckConstraint(
name="check_%(class)s_size_gt_0",
condition=models.Q(size__gt=0),
)
]
class Image(Model):
width = IntegerField()
height = IntegerField()
class Meta:
abstract = True
constraints = [
CheckConstraint(
name="check_%(class)s_width_gt_0",
condition=models.Q(width__gt=0),
),
CheckConstraint(
name="check_%(class)s_height_gt_0",
condition=models.Q(height__gt=0),
),
]
And I would like to use these classes like:
class UserAvatar(File, Image):
class Meta:
db_table = "user_avatar"
This is a pattern I’ve seen in django-otp, for example.
I would expect UserAvatar
to inherit the constraints from both base classes, but it doesn’t seem to work like that.
What do you think? I think as of now, Django cannot handle this kind of multiple inheritance? So maybe it’s best to stick with single inheritance?
Hey @csirmazbendeguz 
This behavior of not combining composite Meta
attributes is not unique to constraints
, it works that way for all other attributes such as
permissions
ordering
default_permissions
indexes
unique_together
indexes
constraints
and has been documented to work this way since the introduction of abstract models.
I believe it works this way to avoid ambiguity in how certain attributes should be combined. For example, should ordering
be additive (A.Meta.ordering
+ B.Meta.ordering
) while respecting __mro__
or continue to use the closest ancestor value even if it’s a collection?
I concede that there’s a stronger argument that can be made for indexes
and constraints
combination from bases but, beyond the backward incompatibility, there are still areas of ambiguity around hidden fields and redefined fields and colliding names.
I believe the idea behind not adding such magic was to avoid the temptation to guess what should be done. I’m sure that if you search Trac or the developer mailing list for a similar feature request for index_together
or unique_together
you’ll find a few discussions.
The introduction of the new constraints
and indexes
options could have been an opportunity to make them behave slightly differently from unique_together
and index_together
in this regard but I fear that changing it would cause more harm than good at this point.
4 Likes
thanks for explaining @charettes , makes sense