Django model class inheritance – default fields and overrides

Question:

I’m attempting to have inherited class templates, so that all my models have certain default fields, and all have default overrides for a few functions like save_model()

If I do it like this, I get the overrides, but then have to go and manually set meta data like db_table…

class ModelExtension(models.Model):
    altered_by = models.CharField(max_length=64)

class SomeModel(ModelExtension):
    class Meta:
        db_table = 'app_somemodel'
    fields = models.CharField()
    ...

Is there a way to get this kind of inheritance working right? So far I either have to do extra work to compensate for the drawbacks of this approach, or I’m plagued by MRO errors.2

Asked By: samurailawngnome

||

Answers:

What’s an MRO error? Have you read the django docs on model inheritance? You can either have Abstract Base Classes, Multi-table inheritance, or proxy models.

http://docs.djangoproject.com/en/stable/topics/db/models/#abstract-base-classes

What you’ve done there is a multi-table inheritance – there’s a hidden OneToOneField connecting your two models. I don’t know why you think you need the db_table specified – it shouldn’t be.

If you are never going to have objects of bare class ModelExtension then you want abstract base classes. In this case you put abstract=True in the Meta section, and then all the fields from the base class are added to the table for the child class. The docs explain it better than I can here.

I often find myself starting to do it one way and then flipping back and forth several times as I think more about my database structure….

Answered By: Spacedman

If you just want to add new functionality to a model without changing its fields, use a proxy model!

Answered By: Bernhard Vallant
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.