Зарегистрируйтесь, чтобы продолжить обучение

Django ORM Python: Разработка на фреймворке Django

Практически любое веб-приложение так или иначе работает с базой данных. При этом с системой управления базами данных (СУБД) приложение общается универсальным способом, например, посредством языка SQL.

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

ORM

ORM (Object-Relational Mapping) — отображение сущностей предметной области и их взаимосвязей в объекты, удобные для использования программистом.

Разные ORM по-разному подходят к тому, насколько нужно изолировать пользователя от конкретного хранилища. Некоторые полностью скрывают всю работу с базой данных. В этом случае мы пользуемся объектами, изменяем их состояние, а ORM неявно синхронизирует состояние объектов и сущностей в хранилище.

Другие ORM только оборачивают сущности базы данных в структуры языка, но все запросы нужно писать вручную. Это два разных полюса, каждый со своими плюсами и минусами. Авторы Django решили остаться где-то посередине.

Если использовать Django ORM, можно работать с объектами и выполнять вручную их загрузку и сохранение. Однако для этого можно использовать привычные средства языка: итерацию, вызов методов.

Django же обеспечивает правильную работу нашего приложения с конкретными хранилищами данных. Эта изоляция от конкретного хранилища позволяет использовать разные базы данных в разных условиях. Например, при разработке и тестировании использовать что-то более легковесное, а на релизном сервере применять рабочую базу данных.

Модель

Любая сущность, которая создается внутри приложения, называется моделью. Модели в Django лежат в директориях приложений в файлах models.py. Конкретный набор моделей зависит от приложения и может измениться со временем. На Хекслете таких моделей сотни, вот лишь некоторые, с которыми наши пользователи сталкиваются каждый день:

  • Пользователь
  • Курс
  • Урок
  • Профессия
  • Упражнение
  • Подписка
  • Участник курса
  • Статья в блоге
  • Топик
  • Комментарий к топику
  • Проект

Важно не путать понятие модель во фреймворке, с понятием модель в MVC. Последнее — это не про класс, файл, функцию или структуру данных. Это слой приложения, который отвечает за модель предметной области. И это не про базу данных.

Слово «модель» часто используется в качестве замены словосочетания «Django ORM», поэтому в рамках курсов будет использоваться этот термин. Модель в единственном числе говорит нам о том, что наша предметная область смоделирована с помощью средств фреймворка. Это собирательный образ слоя хранения. При этом отдельные сущности тоже называются моделями — модели поменьше собираются в большую модель всей предметной области.

Связь между моделями и таблицами в базе данных: одна таблица — одна модель. В этом плане Django ORM не отходит далеко от схемы базы данных. Всегда можно представить, как фактически представлены данные с точки зрения СУБД. Что очень полезно, когда нужно что-то оптимизировать.

Database Engines

К фактической базе данных Django подключается с помощью Database Engines. Одно приложение может подключаться к нескольким базам данных. Это можно сделать и с помощью разных движков. Но такое случается нечасто. Обычно одна база приходится на одно веб-приложение.

Описываются базы данных в словаре settings.DATABASES:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
  • ENGINE указывает на конкретный движок
  • NAME в случае SQLite хранит имя файла. Для других СУБД это будет имя базы данных в удобном для них формате
  • default — имя базы данных уже для самого Django

Когда используется несколько баз данных одновременно и имя другой не указано в коде явно, эта «база данных по умолчанию» используется всегда.

Описание моделей

Модели описываются в модулях models.py. Каждое приложение имеет свой собственный модуль models.py, в котором содержатся описание моделей конкретного приложения.

Добавим в hexlet_django_blog.article.models следующий код:

from django.db import models

class Article(models.Model):
    name = models.CharField(max_length=200) # название статьи
    body = models.TextField() # тело статьи
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

Article — это и есть наша первая модель. У нее четыре поля:

  • created_at — для хранения даты и времени создания записи
  • updated_at — для хранения даты и времени последнего изменения записи
  • name— для хранения названия статьи
  • body — для хранения текста статьи

В этом случае мы не описываем поле id, которое обычно является первичным ключом. В models.Model оно уже описано, и нам не нужно это делать дополнительно. Но мы его можем переопределить.

Со стороны Python всё готово. Но еще нужно сделать так, чтобы соответствующая таблица появилась в базе данных. Для этого необходимо сгенерировать миграцию.

Миграция

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

Чтобы получить миграцию, выполняем команду:

python manage.py makemigrations

Migrations for 'article':
  hexlet_django_blog/article/migrations/0001_initial.py
    - Create model Article

Когда мы запускаем makemigrations, мы сообщаем Django, что внесли изменения в свои модели, например, создали новую модель. Также мы сообщаем о том, что хотим, чтобы эти изменения сохранились как миграция.

Миграции — это описания изменений в наших моделях, и в дальнейшем в схеме базы данных. Мы можем просмотреть эти файлы миграций. Они располагаются в директориях migrations внутри приложений. Например, в нашем случае файл миграции располагается в hexlet_django_blog/article/migrations/0001_initial.py.

Нам не нужно читать все файлы миграций, когда Django их создает. Но при необходимости мы можем их редактировать, чтобы изменить порядок миграции.

Теперь посмотрим, какой SQL-запрос будет выполняться при запуске миграции. Для этого воспользуемся командой sqlmigrate:

python manage.py sqlmigrate article 0001

BEGIN;
--
-- Create model Article
--
CREATE TABLE "article_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(200) NOT NULL, "body" text NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
COMMIT;
  • Имена таблиц автоматически генерируются с помощью объединения имени приложения (article) и имени модели в нижнем регистре — article
  • Поле id, которое является первичным ключом, добавляется автоматически

Применяем все остальные миграции. Эта операция идемпотентна:

python manage.py migrate

Operations to perform:
  ...
Running migrations:
  ...
  Applying article.0001_initial... OK
  ...

Созданная миграция была применена. Если все прошло успешно, то в базе данных появилась таблица article_article.

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

Миграции можно не только накатывать, но и откатывать. Для этого нужно указать версию миграции, к которой мы хотим вернуться.

Например, в директории migrations приложения article у нас есть два файла миграции 0005_second_last_migration и 0006_last_migration. 0006 — это последняя примененная миграция.

Если нам нужно вернуться к миграции 0005 из миграции 0006, мы выполним следующую команду:

python manage.py migrate article 0005

Если нам нужно отменить все миграции этого приложения, нужно указать zero в качестве версии миграции:

python manage.py migrate article zero

Иногда миграция может быть необратимой. Как правило, это возникает, когда в модели вносятся существенные изменения. Когда мы попытаемся вернуться к такой миграции, Django выдаст ошибку IrreversibleError.


Самостоятельная работа

  1. Создайте модель Article
  2. Выполните миграции

Дополнительные материалы

  1. Models
  2. Migrations

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Программирование на Python, Разработка веб-приложений и сервисов используя Django, проектирование и реализация REST API
10 месяцев
с нуля
Старт 2 января

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»