Django-проект должен хранить массу данных: посты пользователей, информацию о самих пользователях, большое количество технической информации. Пора подготовить код к взаимодействию с базой данных.
Объекты классов и объекты в базе данных
Классы описывают новые типы объектов и позволяют создавать экземпляры таких объектов.Записи в базах данных тоже описывают объекты — наборы свойств, которыми можно управлять. Вы уже пережили множество прекрасных мгновений, работая с SQL-запросами. Есть способ связать данные объектов с записями в БД, упростить и автоматизировать стандартные операции и при этом обойтись без запросов на SQL. Всё это делает Django ORM — Object-Relational Mapping, «объектно-реляционное отображение». Object — объекты, которые созданы на основе классов, relational — реляционные базы данных, а mapping — связь между системой объектов и базами данных.Django ORM — это инструмент для работы с данными реляционной БД посредством классов, которые создаёт сам программист. Реализаций ORM существует много, работать мы будем с ORM, встроенной в Django.Первая практическая задача в проекте «Анфиса для друзей»: в базе данных проекта должен храниться список сортов мороженого.Прежде чем начать писать код, необходимо определить, какими полями должен быть описан объект «Мороженое».
- Название мороженого.
- Описание мороженого.
- Должно ли оно отображаться на главной странице?
Структура есть. Теперь можно описать этот объект в виде класса:
class IceCream:
def __init__(self, name, description, on_main):
self.name: str = text
self.description: str = description
self.on_main: bool = on_main
С этим кодом уже можно работать. Но в Django есть классы, специально предназначенные для работы с базой данных.
Модели в ORM
Классы, с которыми работает ORM, называются моделями. В Django ORM есть предустановленный класс Model, от которого разработчик может наследовать собственные модели. У этого класса есть множество предустановленных свойств и методов, обеспечивающих работу с БД.
# Объявляем класс IceCream, наследник класса Model из пакета models
class IceCream(models.Model):
# Описываем поля модели и их типы
# Тип: CharField (строка с ограничением длины)
name = models.CharField(max_length=200)
# Тип: TextField (текстовое поле)
# используется для больших текстовых блоков
description = models.TextField()
# Тип: булева переменная, «да/нет»;
# значение по умолчанию: True
on_main = models.BooleanField(default=True)
Django Coding Style рекомендует описывать содержимое модели в определённом порядке:
- Поля базы данных.
- Настраиваемые атрибуты менеджера.
class Meta
.def __str__()
.def save()
.def get_absolute_url()
.- Другие пользовательские методы.
В проекте Yatube тоже потребуются модели, в первую очередь модель для хранения постов. Будет логично назвать её Post. В этой модели должны быть поля, в которых будут храниться:
- текст поста,
- дата публикации поста,
- автор поста.
class Post(models.Model):
# Тип: TextField
text = models.TextField()
# Тип поля: DateTimeField, для хранения даты и времени;
# параметр auto_now_add определяет, что в поле будет автоматически
# подставлено время и дата создания новой записи
pub_date = models.DateTimeField(auto_now_add=True)
# Тип: ForeignKey, ссылка на модель User
author = models.ForeignKey(User, on_delete=models.CASCADE)
Для всех моделей Django ORM создаст в БД таблицы.Свойства модели, описанные через синтаксис имя_свойства = models.тип_данных()
, определят названия и типы данных в колонках таблицы БД.Так, для модели Post в базе данных будет создана таблица с колонками text, pub_date и author, причём в колонке author должны быть указаны primary keys записей из таблицы User*.*Магия ORM состоит в том, что после создания модели Django автоматически проведёт массу операций:
- Создаст необходимые таблицы в базе данных.
- Добавит первичный ключ (primary key), по которому можно будет обратиться к нужной записи.
- Добавит интерфейс администратора.
- Создаст формы для добавления и редактирования записей в таблице.
- Настроит проверку данных, введённых в веб-формы.
- Предоставит возможность изменения таблиц в БД.
- Создаст SQL-запросы для создания таблицы, поиска, изменения, удаления данных, настроит связи между данными, обеспечив их целостность.
- Предоставит специальный синтаксис формирования запросов.
- Добавит необходимые индексы в базу данных для ускорения работы сайта.
Впечатляющий список.
Подробный взгляд на модель
Напишем полный код модели для управления записями в нашем проекте:posts/models.py
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Post(models.Model):
text = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
В первых строках в код импортируются нужные модули:
from django.db import models
# Из модуля auth импортируем функцию get_user_model
from django.contrib.auth import get_user_model
Для работы с моделями импортируется модуль models
, а для создания поля со ссылкой на модель User импортируется и эта модель: она встроена в Django и отвечает за управление пользователями.Официальная документация рекомендует обращаться к модели User через функцию get_user_model
. Следуем этой рекомендации:
User = get_user_model()
Описание модели начинается с объявления: класс Post — это наследник класса Model из модуля models.
class Post(models.Model):
text = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
Для полей в моделях указывают типы данных, соответствующие типам данных в БД.В коде модели Post описаны поля:
- TextField — поле для хранения произвольного текста.
- DateTimeField — поле для хранения даты и времени. Существуют похожие типы для хранения даты (DateField), промежутка времени (DurationField), просто времени (TimeField).
- ForeignKey — поле, в котором указывается ссылка на другую модель, или, в терминологии баз данных, ссылка на другую таблицу, на её primary key (pk). В нашем случае это ссылка на модель User. Это свойство обеспечивает связь (relation) между таблицами баз данных.
Параметр on_delete=models.CASCADE
обеспечивает связность данных: если из таблицы User будет удалён пользователь, то будут удалены все связанные с ним посты.Другие популярные типы полей:
- BooleanField — поле для хранения данных типа bool.
- EmailField — поле для хранения строки, но с обязательной проверкой синтаксиса email.
- FileField — поле для хранения файлов. Есть сходный, но более специализированный тип ImageField, предназначенный для хранения файлов картинок.
В Django ORM есть и другие типы полей. Документация даёт полное описание базовых полей, но есть расширения, добавляющие новые типы полей или переопределяющие базовые типы.