I ask myself if it make sense to override save method in a mixin.
In my project I have, for good reasons, to override the save method in several models.
At first, I have to create a custom model class which inherit from models.Model
.
However semantically, what I am doing is giving a role to a class (rather than defining an object in its own right), that's why I think it's better to write a mixin.
An other reason is because we may use multiple inheritance in near future.
On the over hand, this line in overriden save method :
super(MyMixin, self).save(*args, **kwargs)
does not make sens as it can only be used with a django.db.models.Model class.
class MyMixin(object):
def save(self, *args, **kwargs):
...
super(MyMixin, self).save(*args, **kwargs)
...
Could you help me decide the best choice ? (Mixin or custom model)
The way the mro (method resolution order) works, both methods are perfectly valid. The abstract model case is quite simple: you have a single inheritance chain, and each call to super is called on the next class up in the chain. So if you have:
class MyBaseModel(models.Model):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
class MyModel(MyBaseModel):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
The call in MyModel
will propogate to MyBaseModel
, and the call in MyBaseModel
will propogate to models.Model
.
With multiple inheritance, the inheritance chain is slightly different. The first class upwards in the inheritance chain is the first base class defined. So if you have class MyModel(MyMixin, models.Model)
, MyMixin
will be the first class upwards. Next, when super()
is called in MyMixin
(with a MyModel
instance), it will look for siblings of the MyMixin
class. That means that the next method to be called is the save
method on models.Model
.
Considering this, it is perfectly fine to use a mixin to override the save methods. In both cases, the MyModel
save method will be called first, then the mixin/abstract model's save method, and finally the models.Model
save method.
Note:
This is a simplified explanation of the method resolution order that works in this specific case. The actual algorithm for determining the order is the C3 linearization algorithm. A complete explanation can be found here.
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