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 putabstract=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.
- [Django]-Please suggest some alternative to Drupal
- [Django]-Best option for Google App Engine Datastore and external database?
- [Django]-Calculating distance between two points using latitude longitude and altitude (elevation)
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:
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: