Задать вопрос

Как оптимизировать запрос django-mptt?

Привет.
Есть вот такая модель категории товаров.

Модель Category

class Category(MPTTModel):
    name = models.CharField(max_length=50)
    slug = models.SlugField(allow_unicode=True, db_index=True)
    parent = TreeForeignKey(
        "self",
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name="children"
    )



В каждом шаблоне делаю доступной переменную categories, в которую помещаю все категории из бд через контекстный процессор:

Контекстный процессор

def categories(_: HttpRequest) -> dict[str, Any]:
    return {
        "categories": Category.objects.all(),
    }



В шаблоне каталога товаров (в сайдбаре) есть вот такой код (делал по примеру из документации), который выводит полностью всё дерево:

Шаблон

{% if categories %}
        <section class="sidebar-section sidebar__section">
            <div class="sidebar-section__title">
                Категории товаров
            </div>

            <div class="category-nav">
                <ul class="category-nav__list">
                    {% recursetree categories %}
                        <li class="category-nav__item">
                            <a class="category-nav__link" href="{{ node.get_absolute_url }}">
                                {{ node.name }}
                            </a>

                            {% if not node.is_leaf_node %}
                                <button class="category-nav__btn" type="button">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="11" height="6" fill="none" viewBox="0 0 11 6">
                                        <path stroke="#2E2E2E" stroke-linecap="round" stroke-linejoin="round" d="m1 1 4.456 4.386L9.914 1" />
                                    </svg>
                                </button>

                                <div class="category-nav category-nav--sub">
                                    <ul class="category-nav__list">
                                        {{ children }}
                                    </ul>
                                </div>
                            {% endif %}
                        </li>
                    {% endrecursetree %}
                </ul>
            </div>
        </section>
    {% endif %}



И примерно такой же код есть в шапке, чтобы вывести все категории в навигации.

Когда захожу на страницу каталога (где есть сайдбар с категориями), в таблицу с категориями идет 7 запросов. Если закомменчу сайдбар, то будет 4 запроса. Но почему? И на другие страницы, где нет сайдбара с категориями я захожу, там тоже запросов меньше.
То есть когда 2 раза вывожу одно и тоже дерево он почему-то делает больше запросов. Но ведь я один раз получил все категории в контекстном процессоре. Трудность еще в том, что я не знаю алгоритм Nested Set, который используется в этой библиотеке и подумал, может кто подскажет здесь, нормальная ли у меня ситуация. Сколько должно быть запросов для вывода всего дерева?

UPD: я тут посмотрел, что запросы дублируются: 1 запрос идет из контекстного процессора на получение всех категорий.
3 запроса для вывода дерева в навигации и 3 запроса для вывода в сайдбаре. Если сайдбара нет, то минус 3 запроса.

Вот сами запросы, вывел в шаблоне через переменную sql_queries:

SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC 	0.002

SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" WHERE "shop_category"."id" = 3 ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC 	0.001
SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" WHERE "shop_category"."id" = 1 ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC 	0.001
SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" WHERE "shop_category"."id" = 2 ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC 	0.001

SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" WHERE "shop_category"."id" = 3 ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC 	0.001
SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" WHERE "shop_category"."id" = 1 ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC 	0.001
SELECT "shop_category"."id", "shop_category"."name", "shop_category"."slug", "shop_category"."parent_id", "shop_category"."lft", "shop_category"."rght", "shop_category"."tree_id", "shop_category"."level" FROM "shop_category" WHERE "shop_category"."id" = 2 ORDER BY "shop_category"."tree_id" ASC, "shop_category"."lft" ASC
  • Вопрос задан
  • 82 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
@h3ckphy Автор вопроса
Это был какой-то баг. Создал новое приложение, перенес все туда. Теперь запрос только 1.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
Strikt Москва
от 100 000 до 180 000 ₽
ITK academy Саратов
от 75 000 ₽
Sim-Ba Pay Санкт-Петербург
от 180 000 ₽