Skip to content

Extending Django Model

Abstract Model Class

Create an abstract model class that inherits from Django's Model class and define properties in the abstract model class. Steps:

  1. Extract common fields and methods to a new base class.
  2. Set abstract = True in the Meta class of this base class.
  3. Let the original model inherit this abstract base class.
  4. Different subclasses can add their own fields as needed.

Base class properties can include:

  • Creation time, modification time, deletion time
  • Creator, modifier, deletor
  • Table description
python
from django.db import models

# Extract common fields
class BaseModel(models.Model):
    name = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True  # Key: Mark as abstract base class, no database table generated
        ordering = ['-created_at']
    
    def __str__(self): 
        return self.name

Model Class Inheriting Abstract Model Class

Create a normal model class that inherits the abstract model class and define properties in the normal model class.

python
class Product(BaseModel):
    price = models.DecimalField(max_digits=10, decimal_places=2)
    # Automatically has name, created_at, updated_at fields

Remove Unneeded Extended Properties

If some extended properties are not needed, you can handle it as follows.

python
class Category(BaseModel):
    updated_at = None
    description = models.TextField()
    # Automatically has name, created_at fields, but no updated_at

Redefine Extended Properties

If a field defined in the subclass has the same name as a base class field, the subclass field will override the base class field.

python
class Product(BaseModel):
    price = models.DecimalField(max_digits=10, decimal_places=2)
    # Automatically has name, created_at, updated_at fields
    class Meta:
        ordering = ['name']
    # Override sorting field

Referencing Abstract Model Class

For example, place the base class in django_project/utils/models.py file for global reference.

python
from django.db import models

# Extract common fields
class BaseModel(models.Model):
    name = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True  # Key: Mark as abstract base class, no database table generated
        ordering = ['-created_at']
    
    def __str__(self): 
        return self.name

Inherit BaseModel in other models

python
from uitils.models import BaseModel
class User(BaseModel):
    username = models.CharField(max_length=100)

Released under the [BY-NC-ND License](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.en).