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

Как лучше оптимизировать SQL?

Есть код на Джанго, выводит на страницу 3 категории товаров в отдельные табы. Можно ли как то ещё оптимизировать код?

def catalog(request):
    wallets = Products.objects.filter(gender="men", categories=1).select_related("gender", "categories").only("id", "title", "price", "image")
    bags = Products.objects.filter(gender="men", categories=2).select_related("gender", "categories").only("id", "title", "price", "image")
    belts = Products.objects.filter(gender="men", categories=3).select_related("gender", "categories").only("id", "title", "price", "image")
    contex = {"wallets": wallets, "bags": bags, "belts": belts}
    return render(request, 'catalog.html', context)
  • Вопрос задан
  • 98 просмотров
Подписаться 1 Средний 5 комментариев
Решения вопроса 1
nnnLik
@nnnLik
Capybara god
можно сделать лишь один запрос в бд вместо n количество зависящее от количества категорий.

from django.db.models import Q
from collections import defaultdict

def catalog(request):
    categories = {
        1: "wallets",
        2: "bags",
        3: "belts",
...
    }

    products = Products.objects.filter(gender="men").filter(categories__in=categories.keys()). select_related("gender", "categories").only("id", "title", "price", "image")

    categorized_products = defaultdict(list)

    for product in products:
        category = categories[product.categories_id]
        categorized_products[category].append(product)

    context = categorized_products
    return render(request, 'catalog.html', context)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
solotony
@solotony
покоряю пик Балмера
1) зачем нужен `select_related("gender", "categories")` ? ведь и то и другое не являются relations

2) всегда ли gender="man" ?

в итоге я бы сделал так

GENDER_CATEGORIES = [
    ("men", 1),  
    ("men", 2),  
    ("men", 3)   
]

from django.db.models import Q

def catalog(request):
    filters = [Q(gender=gender, categories=category_id) for gender, category_id in GENDER_CATEGORIES]
    query = Q()
    for q_filter in filters:
        query |= q_filter

    products = Products.objects.filter(query).only("id", "title", "price", "image")

    products_by_category = {category[1]: [] for category in GENDER_CATEGORIES}
    for product in products:
        for gender, category_id in GENDER_CATEGORIES:
            if product.gender == gender and product.categories == category_id:
                products_by_category[category_id].append(product)
                break

    context = {"products_by_category": products_by_category}
    return render(request, 'catalog.html', context)


ну и еще в тапл добавить имя 3-м параметром
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы