Model Inheritance

Model Inheritance

Hello and welcome, In this post we will look into how we can create better robust models with a focus on the DRY(Don't Repeat Yourself) principle. At the end of post, you will be familiarized with

  • What Model Inheritance is

  • Types of Model Inheritance

  • Model Inheritance in Action

Model Inheritance

Sometimes while writing model definitions, you might get to the point where you have two tables with almost the same columns and thus you don't see a need to repeat yourself which is best practice, A solution to this is to extend existing table fields into new table fields. That is, the new table to be created can inherit the already existing columns from the already existing table.

For instance, If you want to create a User table for your application and then you listed out the columns to be created as first_name, last_name, email, password, is_verified, image, date_joined, last_login but you now remember that Django has built-in User model with almost all columns you need and so you can just extend Django user model and just add the columns not present.

Type of Model Inheritance

Base Model Inheritance

This type of inheritance has the base model as an abstract model i.e. the model is not created in the database when the migrate command is run and thus it just serves as a template which other models can pick up from. For Django to see a model as a base model the Meta class attribute needs to be updated to have the attribute "abstract = True". For instance,

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length = 250)
    last_name = models.CharField(max_length = 250)
    email = models.EmailField()

    class Meta:
         abstract = True

If you run makemigrations command, you will see that Django will take no actions since the model is abstract. Thus abstract model can be extended as shown below

class Student(Person):
    matric_number = models.CharField(max_length = 50)
    graduated = models.BooleanField(default = False)

Now after running makemigrations, Django now prepares our model for the migrate command and the migration file has been created as shown below

Screenshot (334).png

Proxy Model Inheritance

Proxy models are models that are inherited from another model but are not meant to be created in the database. This kind of model is created when you only want to change the Python behavior of a model – perhaps to change the default manager, or add a new method. Like an abstract model, we need to tell Django the model is a proxy model by stating it in the metaclass as shown below

class StudentProxy(Student):
    class Meta:
        proxy = True

running makemigrations command will generate another migrations file which will not create another table but will ensure that the new proxy model acts on the same table its parent models act.

Screenshot (335).png

Writing a method on the proxy model instead of the base model, this method can be used to have a cool admin page section as shown below

#In models.py file

class StudentProxy(Student):
    class Meta:
        proxy = True

    def is_graduated(self):
        return self.graduated

#In admin.py file
from .models import Student, StudentProxy
@admin.register(StudentProxy)
class StudentProxyAdmin(admin.ModelAdmin):
    list_display = ["first_name", "last_name", "is_graduated"]
    read_only_fields = ['is_graduated']

It's worth noting that when an instance is created in the base model in which a proxy model inherits from such instance appears automatically for the proxy model also.

Screenshot (336).png

Screenshot (337).png

And that's it for now, till we meet again take care and thank you for reading.