@blackbb

Как правильно вывести меню с использованием django-mptt?

Помогите сформировать код для правильного вывода меню.
Имеется 4 пункта (Главная, Типы перевозок, Компании, Контакты) меню. Пункт Типы перевозок содержит 3 подпункта (авто, море, воздух).
<ul class="header_ul navbar-nav mt-2 mt-lg-0">
                      <li class="nav-item active">
                          <a class="" href="">Главная</a>
                      </li>
                      <li class="nav-item dropdown">
                          <a class="dropdown-toggle" href="/port.html" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Типы перевозок</a>
                          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                            <a class="dropdown-item" href="#">Море</a>
                            <a class="dropdown-item" href="#">Воздух</a>
                            <a class="dropdown-item" href="#">Авто</a>
                          </div>
                      </li>
                      <li class="nav-item">
                          <a class="" href="/companys.html">Компании</a>
                      </li>
                      <li class="nav-item">
                          <a class="" href="/contact.html">Контакты</a>
                      </li>
                  </ul>

Никак не могу дать ума и вывести подпункты в типах перевозок.
  • Вопрос задан
  • 3059 просмотров
Решения вопроса 1
ri_gilfanov
@ri_gilfanov
Web- and desktop-developer
Место в документации:
https://django-mptt.readthedocs.io/en/latest/tutor...

Пример использования в Интернет-магазине для вывода выпадающего каталога товаров:
https://github.com/ri-gilfanov/python-t/blob/maste...

Если лень вчитываться в весь шаблон, вот вкратце:
{% load static mptt_tags %}

{% recursetree category_tree %}
    <li>
        <a class="btn btn__light" href="{% url 'category' node.pk %}">
            <span style="flex: 1 1 auto;">{{ node.name }}</span>{% if not node.is_leaf_node %}
            <span>&nbsp;</span><span class="fa fa-angle-right"></span>{% endif %}
        </a>
        {% if not node.is_leaf_node %}
            <ul  class="site_nav_primary__submenu ul__column white_box">
                {{ children }}
            </ul>
        {% endif %}
    </li>
{% endrecursetree %}


Переменная шаблона category_tree -- это дерево категорий, формируемое в контекст-процессоре, посмотреть его можно тут:
https://github.com/ri-gilfanov/python-t/blob/maste...

А модель категорий можно найти тут:
https://github.com/ri-gilfanov/python-t/blob/maste...

В разметке из шаблона выше, каждый элемент дерева категорий именуется node (т.е. узел). В общем-то, это обычный объект модели Django ORM.

Скажем, формирование ссылки:
<a class="btn btn__light" href="{% url 'category' node.pk %}"></a>


В одном из urls.py есть route (маршрут) с именем category, принимающий id категории. Обычно, node.pk и node.id -- это одно и то же, но я предпочитаю брать .pk, чтобы независеть от реального названия первичного ключа.

А вот этот фрагментик из фрагмента выше:
{% if not node.is_leaf_node %}
    <ul  class="site_nav_primary__submenu ul__column white_box">
        {{ children }}
    </ul>
{% endif %}


...значит следующее. Если узел (node) верхнего уровня содержит дочерние узлы, то мы делаем вложенные маркерованные списки (ul) с особыми стилями CSS, а переменная {{ children }} означает, что внутри тегов с каждым дочерним элементом будет происходить всё то же самое, что и с узлами верхнего уровня.

Если псевдокодом на русском:
{% рекурсивное_дерево дерева_категорий %}
    Открываем HTML-теги для узлов верхнего уровня
    и что-то делаем с узлами верхнего уровня.
        {% если узел верхнего уровня содержит дочерние узлы %}
            открываем html-теги, в которые хотим завернуть дочерние узлы
                {{ дети }}
            закрываем html-теги
        {% конец если про детей %}
    Если нужно, ещё что-то делаем с узлами верхнего уровня
    и закрываем HTML-теги.
{% конец рекурсивного дерева %}


Правда, в примере из интернет-магазина, я делаю проверку на наличие дочерних узлов дважды.

Первый раз, я использую её чтобы добавить "небездетным" узлам иконку со стрелочкой, чтобы пользователь знал, что можно навести мышкой и выпадут дочерние категории.

Таким образом, эту проверку можно использовать в разных местах, если нужно по-разному оформить узды с детьми и узлы без детей.

Извиняюсь, если изложил немного путанно. Однако, разобраться во всех возможностях django-mptt можно за один вечер. Документация есть, а при сложностях с английским можно воспользоваться онлайн-переводчиками.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы