Использование абстрактных моделей в Django‎

Одним из принципов Python является DRY (Don’t Repeat Yourself) — «Не повторяйся».  Абстрактные модели в Django предназначены именно для этого.‎

Создать и понять абстрактные модели в Джанго просто, для этого мы разберем такой пример:

Мы разрабатываем базу систему для управления институтом, в Джанго нам понадобятся модели Студенты, Преподаватели и т.п.

Начав создавать соответствующие модели мы увидим, что они имеют много общего кода:

Нарушение принципа DRY в модели 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.

В заключении повторю еще раз, что сами по себе абстрактные модели бесполезны, для них не будет создаваться таблица в базе данных.

Абстрактные модели полезны когда вы планируете создавать модели, которые будут наследовать их поля, чтобы избавится от дублирования кода.

Хостинг для ваших проектов