Как оптимизировать запрос 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
  • Вопрос задан
  • 29 просмотров
Решения вопроса 1
@h3ckphy Автор вопроса
Это был какой-то баг. Создал новое приложение, перенес все туда. Теперь запрос только 1.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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