[Django]-Are django abstract models really that useful?

2👍

From the docs

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.

Personally I have found that one of many advantages of using abstract models is they allow in software extension and prohibit modifications as per SOLID principles.

4👍

An abstract model is used to reduce the amount of code, and implement common logic in a reusable component.

For example if you have a lot of models where you want to define two timestamps for created_at and updated_at, then we can start with a simple abstract model:

class UpdatedCreated(models.Model):
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True

If we now have three models where we want to include these timestamps we can work with:

class Foo(UpdatedCreated):
    other=models.CharField()


class Bar(UpdatedCreated):
    another=models.CharField()


class Qux(UpdatedCreated):
    an_another=models.CharField()

now these three models will all have a created_at and updated_at field. If we define methods on the UpdatedCreated, then the models will inherit this. We can for example make a field that specifies if the item is still "alive" with:

from django.utils.timezone import now

class UpdatedCreated(models.Model):
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    @property
    def alive(self):
        return (now() - updated_at).days < 7

    class Meta:
        abstract = True

It is thus a way to easily extend models by the same reusable component.

1👍

A database table is not created from the class which has "abstract=True" and a child class cannot inherit the fields from the parent class which doesn’t have "abstract=True".

For example, "Student" class extends "Person" class which has "id"(Hidden), "name" and "age" fields as shown below:

# "myapp/models.py"

from django.db import models

class Person(models.Model):
   name = models.CharField(max_length=100)
   age = models.IntegerField()

class Student(Person):
   pass

Then, run this command below:

python manage.py makemigrations && python manage.py migrate

Then, "myapp_person" and "myapp_student" tables are created from "Person" and "Student" classes respectively and because "Student" class doesn’t inherit 3 fields from "Person" class, "myapp_student" table doesn’t have them, instead it has "person_ptr_id" as shown below:

enter image description here

Now, add "abstract = True" to "Person" class as shown below:

# "myapp/models.py"

from django.db import models

class Person(models.Model):
   name = models.CharField(max_length=100)
   age = models.IntegerField()

   class Meta:
      abstract = True # Here

class Student(Person):
   pass

Then, run this command below:

python manage.py makemigrations && python manage.py migrate

Then, only "myapp_student" table is created from "Student" class and because "Student" class inherits 3 fields from "Person" class, "myapp_student" table has them as shown below:

enter image description here

Leave a comment