Azeez Aremu
Django way

Django way

Model Inheritance

Model Inheritance

Azeez Aremu's photo
Azeez Aremu

Published on Sep 4, 2021

3 min read

Subscribe to my newsletter and never miss my upcoming articles

Hello and welcome, In this post we will look into how we can create better robust models with 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 models definitions, you might got to the point where you have two tables with almost same columns and thus you don't see a need to repeat yourself which is best practice, A solution to this is to extends an existing table fields into new table field. That is, the new table to be created can inherits 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 create 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 extends 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 an abstract model i.e the model is not created in the database when migrate command is run and thus it just serve as 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 an abstract model. 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 prepare our model for migrate command and 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. These kind of models are 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 abstract model, we need to tell Django the model is proxy model by stating it in the meta class 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 new proxy model acts on the same table it's parent models acts.

Screenshot (335).png

Writing a method on the proxy model instead of the base model, this method can be used to better have 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.

 
Share this