Django 16. Модель категорий
В этом посте напишем модель категории с применением Django-MPTT.
Дополнительные материалы
Для скачивания материалов необходимо войти или зарегистрироваться
Файлы также можно получить в Telegram-боте по коду: 157101
Реклама
В следующих постах сосредоточимся на следующем функционале:
- Разделы категорий
- Посты
- Поиск по сайту
Стоит отметить, что у меня достаточно поверхностные знания и навыки в вёрстке, по этому примеры шаблонов будут максимально простыми.
Начнём с категорий.
При создании модели категорий, мы будем использовать не встроенный в Django класс модели, а библиотеку django-mptt
.
MPTT - это метод хранения и обработки иерархических данных в базе данных. Библиотека django-mptt
позволит создавать и работать с иерархиями. Проще говоря, мы сможем сделать древовидное представление категорий.
Установка библиотеки.
Установим библиотеку pip install django-mptt
и добавим её в requirements.txt
.
И пропишем в файле settings.py
, добавив mptt
в список INSTALLED APPS
.
Создание модели.
Откроем файл models.py
и создадим класс CategoryModel
наследующий MPTTModel
.
Необходимо создать поля:
- Заголовок - строковое поле с названием категории
- Слаг/Slug - поле, формирующее из строки заголовка - slug-строку. Slug формируется только из ASCII символов, цифр и дефисов.
- Родитель - внешний ключ на родительскую категорию. Поскольку используется
MPTTModel
, то вместо стандартногоForeignKey
используетсяTreeForeignKey
. - Описание - строковое поле, содержащее описание категории
Так же класс Meta
, содержащий название модели и определяющий уникальную пару полей.
Класс MPTTMeta
с сортировкой по вложенностям.
Метод get_absolute_url
, возвращающий URL-адрес для объекта модели.
И последним будет dunder-метод __str__
, возвращающим заголовок.
from django.urls import reverse
from mptt.managers import TreeManager
from mptt.models import MPTTModel, TreeForeignKey
class CategoryModel(MPTTModel):
title = models.CharField(max_length=100,
verbose_name="Заголовок")
slug = models.SlugField(verbose_name="Альт. заголовок")
parent = TreeForeignKey('self',
on_delete=models.CASCADE,
null=True,
blank=True,
related_name='children',
db_index=True,
verbose_name='Родительская категория')
description = models.CharField(max_length=350,
verbose_name="Описание",
blank=True)
objects = TreeManager()
class MPTTMeta:
order_insertion_by = ['title']
class Meta:
unique_together = 'parent', 'slug'
verbose_name = 'Категория поста'
verbose_name_plural = 'Категории постов'
def get_absolute_url(self):
return reverse('blog:category_page', args=[int(self.pk), str(self.slug)])
def __str__(self):
return self.title
Про поле parent
.
В поле создаётся объект класса TreeForeignKey
из django-mptt
, позволяющий делать древовидные категории. Аргумент self
указывает, что внешний ключ ссылается на ту же модель, в которой он определен, то есть на CategoryModel
.
Аргумент on_delete=models.CASCADE
задает поведение при удалении связанного объекта. В данном случае, если родительская категория удалена, то все дочерние категории также будут удалены.
Аргументы null=True
и blank=True
позволяют полю parent
быть необязательным и не требуют обязательного ввода значения при создании объекта.
Аргумент related_name='children'
определяет имя обратной связи между родительской и дочерней категорией. То есть, у каждого объекта модели CategoryModel
будет доступ к своим дочерним категориям через атрибут children
.
Аргумент db_index=True
создает индекс в базе данных, что позволяет ускорить поиск и сортировку по этому полю.
Менеджер, Meta и метод получения URL.
В поле objects
будем использовать не обычного Django-менеджера, а специального для работы с MPTTModel
.
В классе Meta
, помимо привычных полей, появилось новое unique_together
. Данное поле определяет какая пара полей модели должны быть уникальными.
Класс MPTTMeta
, делает то же, что и Meta
, только для объектов модели MPTTModeL
. Поле order_insertion_by
определяет порядок вставки новых элементов в дерево. В нашем случае, элементы будут вставляться в порядке возрастания заголовка.
Появился новый метод get_absolute_url
. Данный метод возвращает URL-адрес до страницы объекта.
В следующем посте, займёмся шаблонами, зарегистрируем и протестируем модель позже.
Все статьи