This is a question about Python Mixins that might be useful in general. I'm just using Django models as that is the use-case I'm most familiar with.
Should a mixin inherit from the class it is designed to mix-in with or from 'object'?
Examples by code, what is more correct or better, or better depending on what you want to achieve?
This
class TaggingMixin(models.Model): tag = models.ForeignKey(Tag) class Meta: abstract = True class MyModel(models.Model, TaggingMixin): title = models.CharField(max_length=100)
Or this:
class TaggingMixin(object): tag = models.ForeignKey(Tag) class Meta: abstract = True class MyModel(models.Model, TaggingMixin): title = models.CharField(max_length=100)
I think inheriting from object is the right way. But I'm seeing examples of the first case all over the net...
EDIT: I've moved my follow up question to a separate question: Django Abstract Models vs simple Python mixins vs Python ABCs
Django Models Model mixinsTo turn a model into an abstract class, you will need to mention abstract=True in its inner Meta class. Django does not create any tables for abstract models in the database. However for the models Envelope and Package , corresponding tables would be created in the database.
It's perfectly valid for a mixin to inherit from another mixin - in fact, this is how most of Django's more advanced mixins are made. However, the idea of mixins is that they are reusable parts that, together with other classes, build a complete, usable class.
Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not.
The basics: Each model is a Python class that subclasses django. db. models.
Django does a lot of meta magic when it comes to its model classes, so unfortunately the usual approach to mixins as suggested in Daniel Roseman's answer -- where they inherit from object
-- does not work well in the Django universe.
The correct way to structure your mixins, using the example provided, would be:
class TaggingMixin(models.Model): tag = models.ForeignKey(Tag) class Meta: abstract = True class MyModel(TaggingMixin): title = models.CharField(max_length=100)
Important points here being:
model.Model
but are configured as an abstract class.model.Model
, your actual model should not inherit from it. If you do, this might trigger a consistent method resolution order exception.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