This is a question prompted by another question from me.
Django provides Abstract base classes functionality (which are not to same as ABC classes in Python?) so that one can make a Model (Django's models.Model) from which one can inherit, but without that Model having an actual table in the database. One triggers this behavior by setting the 'abstract' attribute in the Model's Meta class.
Now the question: why does Django solve it this way? Why the need for this special kind of 'Abstract base class' Model? Why not make a Model mixin by just inheriting from the object class and mixing that in with an existing Model? Or could this also by a task for Python ABCs? (mind you I'm not very familiar with ABC classes in Python, my ignorance might show here)
Abstract classes can contain abstract methods, concrete methods and internal state. Like interfaces, mixins do not contain any internal state. But like abstract classes, they can contain one or more concrete methods. So mixins are basically abstract classes without any internal states.
Abstract Base Class are useful when you want to put some common information into a number of other models. You write your base class and put abstract = True in the Meta Class.
An abstract model is a base class in which you define fields you want to include in all child models. Django doesn't create any database table for abstract models. A database table is created for each child model, including the fields inherited from the abstract class and the ones defined in the child model.
Using Django's class-based view Mixins Mixins make use of reusable blocks of code that are only meant to be used with other classes, not be implemented on their own. You are still using inheritance to create your classes, but you have a lot more freedom.
I'll try to be reasonably brief, since this can easily turn into a lengthy diatribe:
ABCs are out because they were only introduced in Python 2.6, and the Django developers have a set roadmap for Python version support (2.3 support was only dropped in 1.2).
As for object-inheriting mixins, they would be less Pythonic in more ways than just reducing readability. Django uses a ModelBase
metaclass for Model
objects, which actually analyses the defined model properties on initialisation, and populates Model._meta
with the fields, Meta
options, and other properties. It makes sense to reuse that framework for both types of models. This also allows Django to prevent abstract model fields from being overriden by inheriting models.
There's plenty more reasons I can think of, all of them minor in themself, but they add up to make the current implementation much more Pythonic. There's nothing inherently wrong with using object-inheriting mixins though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With