Using abstract models in Django
Tags: django, python
Published: 2021-05-23 03:26:36

One of the principles of Python is “Do not repeat yourself”.  Abstract models in Django are meant to do exactly that.

If you are designing a database for a school, there would be database models representing all types of people who attend this school which includes the students, teachers, cleaning staff, cafeteria staff, school bus drivers, etc.

However, all of these folks have some common information such as name, date of birth, date of joining, address and contact information, etc.

It doesn't seem right to repeat all of these fields for each database model while writing the code, and this is where abstract models work great.

## How to create an abstract base model?

All you have to do is create a base model with all the common fields and set abstract = True in the meta class. 

This will ensure that there is no actual database table created for this base model and it is meant only for being inherited by other models that actually become tables in the database.

    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=255)
        date_of_birth = models.DateTimeField()
        date_of_joining = models.DateTimeField()
        address = models.TextField()
    
        class Meta:
            abstract = True
    
    class Student(Person):
        roll_number = models.IntegerField()
    
    
    class Teacher(Person):
        compensation = models.CharField(max_length=255)

After running migrations, there will be a student table and a teacher table created in your database while the person model stays in your codebase ready to be inherited in another model if you chose to.

## Abstract as much as possible

The “Do not repeat yourself” principle does not have to end here. For instance, even though the folks belonging to the cleaning staff and cafeteria staff are also persons, they both have shift timings which students and teachers do not.

    from django.db import models
    
    #======= Abstract models =========#
    class Person(models.Model):
        name = models.CharField(max_length=255)
        date_of_birth = models.DateTimeField()
        date_of_joining = models.DateTimeField()
        address = models.TextField()
    
        class Meta:
            abstract = True
    
    class SchoolEmployee(Person):
        compensation = models.CharField(max_length=255)
    
        class Meta:
            abstract = True
    
    class HiredHelp(SchoolEmployee):
        shift_timings = models.JSONField()
    
        class Meta:
            abstract = True
    #--------------------------------#
    
    #======= Actual models ==========#
    class Student(Person):
        roll_number = models.IntegerField()
    
    class Teacher(SchoolEmployee):
        qualifications = models.JSONField()
    
    class CafeteriaEmployee(HiredHelp):
        pass
    
    class CleaningStaffMember(HiredHelp):
        pass
    #--------------------------------#

Depending on your requirement you can have further abstract models that inherit from other abstract models.

## Closing notes

It is important to keep in mind that abstract models by themselves are quite useless. There is no database table created for them and hence they are of no consequence.

Abstract models are only useful if you intend to create other models which inherit from the abstract ones. 

Abstract classes are a good example of how the concept of inheritance can be used to write reusable code. 

[Originally posted on my blog](https://www.sankalpjonna.com/learn-django/using-abstract-models-in-django)