Модель — это воплощение понятия предметной области в коде приложения. В Django ORM каждая модель представлена классом в коде и таблицей в базе данных:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=100, null=True)
last_name = models.CharField(max_length=100)
nickname = models.CharField(max_length=20, null=True)
# ^ таким образом описанные атрибуты класса называют "полями"
password = models.CharField(max_length=100)
USERNAME_FIELD = 'email'
- Модель представляется классом только в языках с классами. Технически она может быть чем угодно в зависимости от языка.
- Поля модели описывают одноимённые столбцы таблицы и одновременно являются свойствами (properties) класса, что позволяет им следить, например, за присваиваемыми полям значениями. В других ORM и других языках столбцы могут быть описаны иначе.
- Связь "Модель-Таблица" — это особенность паттерна Active Record. В другом подходе, называемом Data Mapper, всё может быть по-другому.
- Поле
USERNAME_FIELD
представляет собой строку, описывающую имя поля в модели пользователя, которая используется в качестве уникального идентификатора. Обычно это какой-то логин, но это также может быть адрес электронной почты или любой другой уникальный идентификатор. Поле должно быть уникальным
Единственное, что нужно для работы модели — создать таблицу в базе данных. Для чего, в свою очередь, потребуется миграция. Django генерирует миграции по команде makemigrations
и применяет по команде migrate
:
poetry run python manage.py makemigrations
poetry run python manage.py migrate
Миграции создаются и сохраняются внутри каждого приложения, что позволяет поставлять миграции вместе с остальным кодом и использовать одни и те же приложения в разных проектах.
После того, как миграции были применены, модель можно использовать: создавать сущности, сохранять их в базу и обновлять:
user = User()
# Присваивание значений атрибутам учитывает тип и настройки полей
user.email = 'user@email.com'
user.first_name = 'Pedro'
user.last_name = 'Rodriges'
# Пароли нельзя сохранять простым присваиванием
user.set_password('rasmuslerdorf')
user.save() # INSERT (добавление новой записи)
user.email = 'pedro@hotmail.com'
user.save() # UPDATE (обновление существующей записи)
user.email # => 'pedro@hotmail.com'
user.delete() # удаление пользователя
Из примера выше видно, что при создании или обновлении сущности, используется метод save()
, а Django ORM сама распознает что происходит: создание или обновление.
Сущности можно также создавать и с помощью метода .create()
у специальной сущности — менеджера. Дело в том, что за каждой моделью закреплён хотя бы один менеджер, получить доступ к которому можно через атрибут .objects
. Менеджер отвечает за операции, относящиеся не к одной конкретной сущности, а к самой таблице. Метод .create()
воздействует на таблицу, создавая в ней новую запись:
User.objects.create(email='foo@bar.baz', first_name='Moe')
# INSERT INTO ...
# ...
# Execution time: 0.009294s [Database: default]
# <User: User object (3)>
После того как сущность сохранена в базу, её можно извлечь. Самый простой способ сделать это - воспользоваться методом .get()
менеджера. Он выполняет поиск по первичному ключу.
moe = User.objects.get(id=3)
# SELECT ...
# ...
moe
# <User: User object (3)>
# Если записи не существует, то будет возбуждено исключение
User.objects.get(id=100500)
# SELECT ...
# ...
# Traceback (most recent call last):
# File "<console>", line 1, in <module>
# ...
# python_django_orm_blog.blog.models.User.DoesNotExist: User matching query does not exist.
Самостоятельная работа
- Зайдите в REPL набрав
make shell
- Создайте нескольких пользователей, обновите их
- Переоткройте REPL и извлеките сущности из базы данных
- Удалите часть сущностей
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.