Create a BaseModel in Django

Sometimes when developing a Django model, you want to have certain columns appear in every database table. A good example (and a good practice) is adding fields representing creation and update date and time fields to each row. Without using the abstract base class, this would mean rewriting the code for each model in your Django application.

So what exactly is an abstract base class?
Here is the definition from the Django documentation:

Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

This is quite neat, since our base class won’t be added to the database as a separate table.

Creating the BaseModel

In your models.py file we want to create a BaseModel that will hold all the data, that you want to appear through all database tables. The BaseModel needs to use the default django.db.models.Model as its base. Our goal with this piece of code, will be adding the two fields responsible for holding created and updated times in a form of a DateTimeField.

from django.db import models


class BaseModel(models.Model):
    created_at = models.DateTimeField(
        auto_now_add=True,
        db_index=True
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        db_index=True
    )

    class Meta:
        abstract = True

Notice how the Meta class has its value set to abstract = True, without this, the BaseModel would appear as a normal database table in the Django environment.

Using the BaseModel

Now, that we have created the model, we should implement it into our database tables. This is quite simple, the only difference you will notice, is that we will replace the django.db.models.Model for our BaseModel for each model that we will create. Below I have presented an example User model utilizing what we have done.

class User(BaseModel):
    name = models.CharField(
        max_length=30
    )

Once the models are migrated the User table will have 3 columns: