tags:

views:

80

answers:

2

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)

+2  A: 

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.

Aram Dulyan
(Marking this as the accepted answer, although Daniel's is also good, but Aram expanded a bit more on the gritty-nitty bits.)Am I correct in understanding that, by using object-inheriting mixins I would be able to declare extra fields on the Model? But I would be able to add extra methods or override them?
hopla
Yes, object-inheriting mixins can declare extra fields and methods. You can override methods by making sure your object-inheriting mix-in comes first in the list of classes to inherit from. However, regardless of the order, an object-inheriting mixin cannot override a field (it will not fail to validate if it tries to though).
Aram Dulyan
+1  A: 

One of the reasons is because of the way fields are defined on a model.

Fields are specified declaratively, in a way that a normal class would treat as class attributes. Yet they need to become instance attributes for when the class is actually instantiated, so that each instance can have its own value for each field. This is managed via the metaclass. This wouldn't work with a normal abstract base class.

Daniel Roseman