Django База [2023]: Создание вложенных категорий с помощью MPTT 🌳 #3
В этой статье мы рассмотрим создание древовидной модели категорий для статей в Django 4.1 с использованием MPTT модуля.
Если вы хотите выразить благодарность автору сайта, статей и курса по Django, вы можете сделать это по ссылке ниже:
Создание вложенной модели категорий (Category)
Перейдем в наше приложение blog и в модели. В прошлом уроке мы создали модель Article
Откройте терминал и запишите следующую команду для установки Django MPTT и Pillow для работы с полем thumbnail: models.ImageField
с помощью команды pip install django-mptt Pillow
После установки модуль MPTT необходимо добавить в INSTALLED_APPS:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'modules.blog.apps.BlogConfig',
'mptt',
]
Теперь перейдем к созданию самой модели Category:
from mptt.models import MPTTModel, TreeForeignKey
class Category(MPTTModel):
"""
Модель категорий с вложенностью
"""
title = models.CharField(max_length=255, verbose_name='Название категории')
slug = models.SlugField(max_length=255, verbose_name='URL категории', blank=True)
description = models.TextField(verbose_name='Описание категории', max_length=300)
parent = TreeForeignKey(
'self',
on_delete=models.CASCADE,
null=True,
blank=True,
db_index=True,
related_name='children',
verbose_name='Родительская категория'
)
class MPTTMeta:
"""
Сортировка по вложенности
"""
order_insertion_by = ('title',)
class Meta:
"""
Сортировка, название модели в админ панели, таблица в данными
"""
verbose_name = 'Категория'
verbose_name_plural = 'Категории'
db_table = 'app_categories'
def __str__(self):
"""
Возвращение заголовка статьи
"""
return self.title
Пояснения:
- order_insertion_by - сортировка по вложенностям
- Наследуемся от MPTTModel
Далее нам необходимо включить категории в модель статей, делается это следующим образом:
class Article(models.Model):
"""
Модель постов для сайта
"""
title = models.CharField(verbose_name='Заголовок', max_length=255)
slug = models.CharField(verbose_name='Альт.название', max_length=255, blank=True, unique=True)
# Другие поля модели...
category = TreeForeignKey('Category', on_delete=models.PROTECT, related_name='articles', verbose_name='Категория')
Мы должны использовать вместо отношения: ForeignKey
импортированное отношение вложенности из модуля MPTT: TreeForeignKey
Регистрируем модель категорий в админке, и добавляем возможность скрывать категории по вложенностям с помощью DraggableMPTTAdmin
:
До этого мы регистрировали уже модель Article.
from django.contrib import admin
from mptt.admin import DraggableMPTTAdmin
from .models import Category, Article
@admin.register(Category)
class CategoryAdmin(DraggableMPTTAdmin):
"""
Админ-панель модели категорий
"""
list_display = ('tree_actions', 'indented_title', 'id', 'title', 'slug')
list_display_links = ('title', 'slug')
prepopulated_fields = {'slug': ('title',)}
fieldsets = (
('Основная информация', {'fields': ('title', 'slug', 'parent')}),
('Описание', {'fields': ('description',)})
)
admin.site.register(Article)
Отлично. Теперь нам необходимо провести миграции в базу данных:
py manage.py makemigrations
py manage.py migrate
Результат выполнения команд:
(venv) PS C:\Users\Razilator\Desktop\Base\backend> py manage.py makemigrations
Migrations for 'blog':
modules\blog\migrations\0001_initial.py
- Create model Category
- Create model Article
- Create index app_article_time_cr_a1fcc0_idx on field(s) -time_create, -fixed of model article
(venv) PS C:\Users\Razilator\Desktop\Base\backend> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying blog.0001_initial... OK
Applying sessions.0001_initial... OK
(venv) PS C:\Users\Razilator\Desktop\Base\backend>
Отлично, миграции проведены. Теперь давайте проверим работоспособность наших моделей в админ-панеле, чтобы в нее войти нам нужно создать супер-пользователя, делается это следующей командой: py manage.py createsuperuser
Вводим свои данные:
Username: Ваш логин
Email address: Ваш Email
Password: Ваш пароль
Password (again): Повтор Вашего пароля
Если все ввели правильно, то пользователь будет создан: Superuser created successfully.
Далее переходим в админ-панель по следующему адресу: http://127.0.0.1:8000/admin/, авторизовываемся и должно получиться вот так:
Отлично, давайте создадим вложенные категории:
Сначала делаем главную категорию:
Далее добавляем вложенную категорию, например Django
Также пример как выглядит возможность скрыть категории по вложенности:
И напоследок добавим статью:
Отлично, у нас все получилось. Вскоре я напишу продолжение по работе по базовому Django.