Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Основные концепции Python: Django ORM

Это обзорный урок, который показывает общие концепции присущие ORM. Каждая из этих концепций будет далее рассматриваться в курсе

ORM (Object-Relation Mapping) – общее название для фреймворков или библиотек, позволяющих автоматически связать базу данных с кодом. Они стараются скрыть существование базы данных настолько, насколько это возможно. Взамен программисту дают возможность оперировать данными в базе через специальный интерфейс. Вместо построения SQL-запросов, программист вызывает простые методы, а всю остальную работу берёт на себя ORM.

>>> user = User()
>>> user.first_name = 'Peter'
>>> user.save()  # сохранение пользователя в базу

Несмотря на общую цель, ORM бывают очень разными. Django ORM относится к наиболее распространённому и простому типу ORM, реализующему шаблон проектирования Active Record. Этот шаблон базируется на идее, что каждой таблице в приложении соответствует один класс (модель). Этот класс отвечает как за реализацию бизнес логики, так и за взаимодействие с базой данных. Последнее обычно появляется в модели за счёт наследования от базового класса ORM.

Кроме Active Record существует шаблон Data Mapper, он например реализован в SQLAlchemy. Этот подход разделяет сущности и код, связанный с базой данных, на два независимых слоя. Такой подход гибче, но при этом сложнее в работе.

Модель

from django.db import models


class User(models.Model):
    email = models.EmailField(unique=True)
    nickname = models.CharField(max_length=100, null=True)

Каждый объект данного класса соответствует одной записи в таблице. За преобразования данных в объекты и обратно, отвечает ORM. Программисту лишь нужно использовать правильные методы для извлечения объектов и их модификации.

>>> # Поиск пользователя по идентификатору
>>> user = User.objects.get(id=1)
>>> # Обновление пользователя
>>> user.nickname = 'Crash and Burn'
>>> # Сохранение в базу
>>> user.save()
>>> # Удаление записи в базе данных
>>> user.delete()
>>> # Общее число пользователей
>>> User.objects.count()
0

Выборки

Важная часть любой ORM — это Query Builder (построитель запросов). Это абстракция поверх SQL, которая упрощает генерацию запросов. Она обычно выглядит как цепочка функций, каждая из которых отвечает за конкретную часть SQL, например: ORDER, SELECT или WHERE.

>>> users = User.objects.order_by('email')[:10]
SELECT "blog_user"."id",
  ...
  FROM "blog_user"
 ORDER BY "blog_user"."email" ASC
 LIMIT 10

Django ORM позволяет описывать достаточно сложные запросы и большинство задач вы сможете решать именно с помощью Query Builder. Однако существует и возможность запросы напрямую:

>>> first_user = User.objects.raw('SELECT * FROM blog_user')[0]
SELECT *
  FROM blog_user

Execution time: 0.002150s [Database: default]

Мы не рекомендуем по умолчанию использовать запросы, написанные вручную. Оставьте эту возможность для тех немногих случаев, когда Query Builder не может сформировать эффективный запрос.

Схема

Ещё одна обязанность ORM – изменение схемы базы данных: добавление, удаление и модификация таблиц. Делается это, как правило, не на чистом SQL, а с помощью специального языка. Это позволяет работать с ORM, не отвлекаясь на особенности конкретных баз данных.

В Django ORM первостепенными являются модели — вы изменяете код, а потом используете средства для приведения схемы базы данных в соответствие новому состоянию кода. Такой подход называется Code First.

Также существует подход Database First: вы сначала меняете базу данных, выполняя SQL-запросы или формируя запросы с помощью средств ORM, а затем ORM уже сама подхватывает изменения и адаптирует модели. Например для добавления нового свойства достаточно добавить новую колонку. В коде ничего менять не нужно, она автоматически начинает работать.

Миграции

Любая база данных в процессе жизни приложения изменяется. В неё добавляются новые таблицы, удаляются старые, какие-то меняются. Этот процесс никогда не заканчивается. Изменения в базе данных выполняются с помощью механизма миграций.

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

Попробуем добавить поле "nickname" к полям модели User из учебного проекта:

# python_django_orm_blog/blog/models.py

class User(models.TimestampedModel):
    """A blog user."""

    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=100, null=True)
    last_name = models.CharField(max_length=100, null=True)
    # это поле - новое!
    nickname = models.CharField(max_length=100, null=True)

Модель изменилась, нужно сгенерировать миграцию:

poetry run python manage.py makemigrations

Migrations for 'blog':
  python_django_orm_blog/blog/migrations/0002_user_nickname.py
    - Add field nickname to user

Теперь миграцию нужно применить:

poetry run python manage.py migrate

Operations to perform:
  Apply all migrations: blog
Running migrations:
  Applying blog.0002_user_nickname... OK

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


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

  1. Документация Django ORM. Django: The model layer.

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

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

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

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
2 февраля 8 месяцев

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

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

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

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»