LukinterLab
LukInterLab

LukInterLab- -LukInterLab

profile-pic

выводим только родительские категории

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 для примеров использования.

Этот пример предоставляет базовую структуру для разделения родительских и дочерних категорий.  Вам, вероятно, придется настроить его в соответствии с вашими конкретными требованиями.

Пока комментариев нет.

Оставьте коментарий