Давайте посмотрим, как взаимодействовать с вариантами статуса. Выполните следующую ниже команду в командной оболочке, чтобы открыть оболочку Python:
python manage.py shell
Затем наберите такие строки:
from blog.models import Post
Post.Status.choices
Вы получите варианты перечисления в формате пар значение–метка, подобные показанным ниже:
[('DF', 'Draft'), ('PB', 'Published')]
Наберите следующую ниже строку:
Post.Status.labels
Вы получите удобочитаемые имена членов перечисления enum, как показано ниже:
['Draft', 'Published']
Наберите следующую ниже строку:
Post.Status.values
Вы получите значения элементов перечисления enum, как показано ниже. Эти значения можно сохранить в базе данных в поле status:
['DF', 'PB']
Наберите такую строку:
Post.Status.names
Вы получите имена вариантов, как показано ниже:
['DRAFT', 'PUBLISHED']
К конкретному искомому перечисляемому элементу можно обращаться посредством Post.Status.PUBLISHED, а также обращаться к его свойствам .name и .value. Чтобы выйти из режима shell используйте комбинацию клавиш Ctrl+Z.
Добавление взаимосвязи многие-к-одному
Посты всегда пишутся автором. Про организацию связей мы с вами говорили в разделе 3.4 "Организация связей между таблицами".
В данном разделе будет создана взаимосвязь между пользователями и постами, которая будет указывать на конкретных пользователей и написанные ими посты.
Django идет в комплекте с фреймворком аутентификации, который ведет учетные записи пользователей. Встроенный в Django фреймворк аутентификации располагается в пакете django.contrib.auth и содержит модель User(Пользователь).
Модель User будет применяться из указанного фреймворка аутентификации, чтобы создавать взаимосвязи между пользователями и постами.
Отредактируйте файл models.py приложения blog, придав ему следующий вид:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Post(models.Model):
class Status(models.TextChoices):
DRAFT = 'DF', 'Draft'
PUBLISHED = 'PB', 'Published'
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique=True)
author = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='blog_posts')
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=2,
choices=Status.choices,
default=Status.DRAFT)
class Meta:
ordering = ['-publish']
indexes = [
models.Index(fields=['-publish']),
]
def __str__(self):
return self.title
Мы импортировали модель User из модуля django.contrib.auth.models и добавили в модель Post поле author.
Это поле определяет взаимосвязь многие-к-одному, означающую, что каждый пост написан пользователем и пользователь может написать любое число постов. Для этого поля Django создаст внешний ключ в базе данных, используя первичный ключ соответствующей модели.
Параметр on_delete определяет поведение, которое следует применять при удалении объекта, на который есть ссылка. Это поведение не относится конкретно к Django; оно является стандартным для SQL.
Использование ключевого слова CASCADE указывает на то, что при удалении пользователя, на которого есть ссылка, база данных также удалит все связанные с ним посты в блоге.
Со всеми возможными опциями можно ознакомиться по адресу https://docs.djangoproject.com/en/5.0/ref/models/fields/#django.db.models.ForeignKey.on_delete
Мы используем related_name, чтобы указывать имя обратной связи, от User к Post. Такой подход позволит легко обращаться к связанным объектам из объекта User, используя обозначение user.blog_posts. Подробнее об этом мы узнаем позже.
Django содержит разные типы полей, которые можно использовать для определения своих моделей. Все типы полей находятся на странице https://docs.djangoproject.com/en/5.0/ref/models/fields/.
Теперь модель Post завершена, и сейчас можно синхронизировать ее с базой данных.