Использование абстрактных моделей в Django
Одним из принципов Python является DRY (Don’t Repeat Yourself) — «Не повторяйся». Абстрактные модели в Django предназначены именно для этого.
Создать и понять абстрактные модели в Джанго просто, для этого мы разберем такой пример:
Мы разрабатываем базу систему для управления институтом, в Джанго нам понадобятся модели Студенты, Преподаватели и т.п.
Начав создавать соответствующие модели мы увидим, что они имеют много общего кода:
Такое повторение кода и нарушает принцим DRY, ну и лишний код вовсе не улучшает читаемость. Вот здесь и понадобяттся абстрактные модели.
Кажется неправильным повторять все эти поля для каждой модели базы данных при написании кода, и именно здесь абстрактные модели отлично работают.
Как создать абстрактную базовую модель Django?
Все, что вам нужно сделать, это создать базовую модель со всеми общими полями и установить в подклассе Meta значение:
abstract = True
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=150, verbose_name='Имя')
date_of_birth = models.DateField(verbose_name='Дата рождения')
email = models.CharField(max_length=150, verbose_name='Email')
home_adress = models.CharField(max_length=250, verbose_name='Домашний адрес')
class Meta:
abstract = True
class Student(Person):
num_book = models.IntegerField(verbose_name='Номер зачетной книжки')
class Teacher(Person):
salary = models.IntegerField(verbose_name='Зарплата')
После выполнения миграции в базе данных будут созданы таблицы студентов и преподавателей содержащие все поля наследуемой ими абстрактной модели Person. Сама таблица Person в базе данных создана не будет.
Кстати можно пойти еще дальше и создать еще одну абстрактную модель — Employee, которая будет унаследована от Person. Ведь все сотрудники института (преподаватель, уборщика, охранник) имею общие поля, например — заработная плата:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=150, verbose_name='Имя')
date_of_birth = models.DateField(verbose_name='Дата рождения')
email = models.CharField(max_length=150, verbose_name='Email')
home_adress = models.CharField(max_length=250, verbose_name='Домашний адрес')
class Meta:
abstract = True
class Employee(Person):
salary = models.IntegerField(verbose_name='Зарплата')
class Teacher(Employee):
experience = models.IntegerField(verbose_name='Стаж/Опыт работы')
class Student(Person):
num_book = models.IntegerField(verbose_name='Номер зачетной книжки')
Выше получается такая последовательность: модель Teacher наследуется от абстрактной модели Employee, которая в свою очередь наследуется от абстрактной модели Person.
В заключении повторю еще раз, что сами по себе абстрактные модели бесполезны, для них не будет создаваться таблица в базе данных.
Абстрактные модели полезны когда вы планируете создавать модели, которые будут наследовать их поля, чтобы избавится от дублирования кода.