
выводим только родительские категории
12 февраля 2025 г. 22:18
РЕШЕНИЕ :
Предполагаем, что у вас есть модель Category, унаследованная от MPTTModel и переменная categories, содержащая queryset всех категорий Оглавление с родительскими категориями
<div class="table-of-contents">
<h2>Содержание</h2>
<ul>
{% for category in categories %}
{% if category.is_root_node %}
<li><a href="#category-{{ category.id }}">{{ category.name }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>
{# Основной контент со всеми категориями и подкатегориями #}
<div class="main-content">
{% for category in categories %}
<div id="category-{{ category.id }}">
<h3>{{ category.name }}</h3>
<p>{{ category.description }}</p> {# Предполагаем, что у категории есть поле description #}
{# Рекурсивный вывод дочерних категорий (если нужно углубленное отображение) #}
{% if category.get_children %}
<ul>
{% for child in category.get_children %}
<li>
<h4>{{ child.name }}</h4>
<p>{{ child.description }}</p>
{# Рекурсивный вызов для внучатых категорий (если необходима более глубокая вложенность) #}
{% if child.get_children %}
<ul>
{% for grandchild in child.get_children %}
<li>
<h5>{{ grandchild.name }}</h5>
<p>{{ grandchild.description }}</p>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
</div>
Пояснения:
categories: Предполагается, что в контексте шаблона доступна переменная categories, которая является QuerySet'ом, содержащим все объекты вашей модели Category (или только те, которые вам нужны для отображения). Этот QuerySet нужно передать из View в шаблон.
category.is_root_node: Это метод MPTTModel, который возвращает True, если категория является корневой (то есть, не имеет родителя). В оглавлении мы выводим только корневые категории.
category.id: Используется для создания якорей (<a href="#category-{{ category.id }}">) и соответствующих div id (<div id="category-{{ category.id }}">). Это позволяет ссылкам в оглавлении переходить к соответствующим разделам в основном контенте.
category.name и category.description: Предполагается, что ваша модель Category имеет поля name (название категории) и description (описание категории). Измените эти названия, если у вас другие поля.
category.get_children: Это метод MPTTModel, который возвращает QuerySet дочерних категорий для данной категории. Используется для рекурсивного отображения структуры дерева категорий в основном контенте.
Рекурсия (необязательно): Добавлен пример рекурсивного вывода внучатых категорий. Если у вас очень глубокая вложенность, тогда этот рекурсивный код нужно или вынести в отдельный template tag (чтобы избежать дублирования кода) или использовать mptt_tags.drilldown_tree (см. документацию django-mptt). Однако, для простой двухуровневой структуры (родительская и дочерняя категории) такой подход вполне приемлем.
Как это использовать:
Определите вашу модель Category: Убедитесь, что ваша модель Category унаследована от MPTTModel.
Передайте QuerySet в шаблон: В вашей view, получите QuerySet всех категорий и передайте его в шаблон.
from django.shortcuts import render
from .models import Category
def my_view(request):
categories = Category.objects.all() # или отфильтруйте, если нужно
return render(request, 'my_template.html', {'categories': categories})
Скопируйте код в ваш шаблон: Скопируйте HTML-код, приведенный выше, в ваш HTML-шаблон.
Настройте стили: Добавьте CSS-стили для table-of-contents и main-content, чтобы они выглядели так, как вам нужно.
Важные замечания:
Производительность: Если у вас очень много категорий, то загрузка всех категорий в одном QuerySet может быть неэффективной. Рассмотрите возможность использования пейджинации или других методов оптимизации запросов к базе данных. django-mptt предоставляет теги для рендеринга дерева, которые могут быть более эффективными для больших деревьев. Изучите документацию django-mptt по тегам шаблонов для более продвинутого использования.
Безопасность: Обязательно экранируйте данные, которые вы выводите в шаблон, чтобы предотвратить XSS-атаки. Django автоматически экранирует данные, но убедитесь, что вы не отключаете экранирование без необходимости.
Альтернативы рекурсии: Для более сложных случаев, лучше использовать mptt_tags.drilldown_tree. Этот тег предназначен для эффективного рендеринга деревьев MPTT. См. документацию django-mptt для примеров использования.
Этот пример предоставляет базовую структуру для разделения родительских и дочерних категорий. Вам, вероятно, придется настроить его в соответствии с вашими конкретными требованиями.
Пока комментариев нет.