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
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.
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.
And that's it for now, till we meet again take care and thank you for reading.