# Abstract models as mixins?

**URL:** <https://forum.djangoproject.com/t/abstract-models-as-mixins/40837>\
**Category:** Using the ORM\
**Created:** [May 8, 2025, 1:18pm UTC](https://forum.djangoproject.com/t/abstract-models-as-mixins/40837 "2025-05-08T13:18:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![csirmazbendeguz](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/csirmazbendeguz/32/19797_2.png) [@csirmazbendeguz](https://forum.djangoproject.com/u/csirmazbendeguz)\
**Post date:** [May 8, 2025, 1:18pm UTC](https://forum.djangoproject.com/t/abstract-models-as-mixins/40837/1 "2025-05-08T13:18:39Z")

</div>

Let’s say I have 2 abstract base classes:

```auto
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:

```auto
class UserAvatar(File, Image):
  class Meta:
    db_table = "user_avatar"

```

This is a pattern I’ve seen in [django-otp](https://github.com/django-otp/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?

---

<div class="post-metadata">

**Author:** ![charettes](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/charettes/32/27_2.png) [@charettes](https://forum.djangoproject.com/u/charettes)\
**Post date:** [May 8, 2025, 2:15pm UTC](https://forum.djangoproject.com/t/abstract-models-as-mixins/40837/2 "2025-05-08T14:15:13Z")

</div>

Hey @csirmazbendeguz 👋

This behavior of not combining composite `Meta` attributes is not unique to `constraints`, it works that way for [all other attributes](https://docs.djangoproject.com/en/5.2/ref/models/options/) such as

- `permissions`
- `ordering`
- `default_permissions`
- `indexes`
- `unique_together`
- `indexes`
- `constraints`

and [has been documented to work this way](https://docs.djangoproject.com/en/5.2/topics/db/models/#meta-inheritance) 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](https://docs.djangoproject.com/en/5.2/topics/db/models/#field-name-hiding-is-not-permitted) 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.

---

<div class="post-metadata">

**Author:** ![csirmazbendeguz](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/csirmazbendeguz/32/19797_2.png) [@csirmazbendeguz](https://forum.djangoproject.com/u/csirmazbendeguz)\
**Post date:** [May 8, 2025, 2:24pm UTC](https://forum.djangoproject.com/t/abstract-models-as-mixins/40837/3 "2025-05-08T14:24:32Z")

</div>

thanks for explaining @charettes , makes sense
