Создание многоуровнего меню
Для хранения древовидной структуры рубрик в БД мы будем использовать Nested Sets (Вложенные множества).
Реализовать данный метод в Django можно при помощи модуля MPTT
pip3 install django-mptt
Создание дополнительное приложения в текущем проекте
В нашем тестовом проекте для целей тестирования мы создадим создадим новое приложение TestApp
python3 manage.py startapp testapp
После в файле settings.py
добавим наше приложение в список приложений:
INSTALLED_APPS = [
# ...
'testapp.apps.TestappConfig',
]
Далее в корневом файле urls.py
добавим путь:
urlpatterns = [
path('test/', include('testapp.urls')),
]
Далее в папке нашего нового модуля testapp
создадим файл urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('', test, name='test')
]
Далее в локальном views.py
описываем контоллер-функцию:
from django.shortcuts import render
def test(request):
return render(request, 'testapp/test.html')
И в папке templates/testapp
создаем test.html
в котором опичываем шаблон отображения.
Добавим в admins.py
наше новое приложение:
from .models import Rubric
admin.site.register(Rubric)
Настройка модуля MPTT
- Добавим приложение MPTT в
settings.py
:INSTALLED_APPS = ( 'django.contrib.auth', # ... 'mptt', )
Добавим модель в
models.py
from django.db import models from mptt.models import MPTTModel, TreeForeignKey class Rubric(MPTTModel): name = models.CharField(max_length=50, unique=True) parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') def __str__(self): return self.name class MPTTMeta: order_insertion_by = ['name']
- Выполняем миграцию:
python3 manage.py makemigrations <your_app>
python3 manage.py migrate
Для тестирования вывода создадим простейший вывод в файле views.py
:
from .models import Rubric
def test(request):
return render(request, "testapp/test.html", {'rubrics': Rubric.objects.all()})
Далее добавляем вывод дерева в файл testapp/test.html
{% load mptt_tags %}
<ul>
{% recursetree rubrics %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
Настройка визуального отображения MPTT в административной панели
Подробнее про визуальную настройку
Настройка отступов
Для добавления отступов в админке достаточно импортировать в admins.py
класс:
from mptt.admin import MPTTModelAdmin
И наследовать его нашим основным класссом MPTT, например так:
admin.site.register(Rubric, MPTTModelAdmin)
Настрока связей с MPTT моделью
Если мы хотим создать модель связанную с MPTT моделью, то это можно сделать так:
class Article(models.Model):
name = models.CharField(max_length=50)
category = TreeForeignKey(Rubric, on_delete=models.PROTECT)
Здесь вместо обчного models.ForeignKey
мы используем TreeForeignKey
. Это необходимо для сохранения вложенности. Не забываем выполнить миграцию.
Визуальное редактирование структуры вложенности в админке (перетаскивание)
Для этого в admins.py
:
from mptt.admin import DraggableMPTTAdmin
admin.site.register(
Rubric,
DraggableMPTTAdmin,
list_display=(
'tree_actions',
'indented_title',
),
list_display_links=(
'indented_title',
),
)