From 2e607a3b388e67c274d1fca876908e2e82ffd287 Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Sat, 27 Dec 2025 21:01:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B2=20=D0=BA=D0=B0=D1=82=D0=B0=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B5=20-=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D1=82=D0=BE=D0=B2=D0=B0=D1=80=D1=8B=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=B7=20=D0=BA=D0=B0=D1=82=D0=B5=D0=B3=D0=BE=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проблема: после оптимизации товары показывались только из категорий, товары без категорий не отображались. Решение: теперь загружаются все активные товары и комплекты напрямую, дополняя список товарами, которые не были загружены через категории. Логика загрузки: 1. Сначала из категорий (используя prefetch кеш) - оптимизация 2. Затем все активные товары напрямую - полнота данных 3. Дедупликация через словари (products_dict, kits_dict) --- myproject/products/views/catalog_views.py | 36 +++++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/myproject/products/views/catalog_views.py b/myproject/products/views/catalog_views.py index 3a34d7a..1fe90d1 100644 --- a/myproject/products/views/catalog_views.py +++ b/myproject/products/views/catalog_views.py @@ -59,28 +59,52 @@ class CatalogView(LoginRequiredMixin, TemplateView): # Строим дерево category_tree = self.build_category_tree(categories, parent=None) - # Извлекаем товары и комплекты из уже загруженных категорий - # Это избегает дополнительных запросов к БД + # Извлекаем товары и комплекты - два способа: + # 1. Из категорий (для оптимизации prefetch) + # 2. Все активные товары напрямую (для товаров без категорий) products_dict = {} kits_dict = {} + # Сначала извлекаем из категорий (используем prefetch кеш) for cat in categories: - # Извлекаем из prefetch_related кеша for p in cat.products.all(): if p.id not in products_dict: p.item_type = 'product' - # main_photo уже загружено через prefetch p.main_photo = p.photos.all()[0] if p.photos.all() else None - # Вычисляем свободное количество p.total_free = p.total_available - p.total_reserved products_dict[p.id] = p for k in cat.kits.all(): if k.id not in kits_dict: k.item_type = 'kit' - # main_photo уже загружено через prefetch k.main_photo = k.photos.all()[0] if k.photos.all() else None kits_dict[k.id] = k + + # Теперь добавляем все товары, которых еще нет (товары без категорий или не загруженные) + all_products = Product.objects.filter(status='active').prefetch_related( + Prefetch('photos', queryset=ProductPhoto.objects.order_by('order')) + ).annotate( + total_available=total_available, + total_reserved=total_reserved, + ).order_by('name') + + for p in all_products: + if p.id not in products_dict: + p.item_type = 'product' + p.main_photo = p.photos.all()[0] if p.photos.all() else None + p.total_free = p.total_available - p.total_reserved + products_dict[p.id] = p + + # Все комплекты + all_kits = ProductKit.objects.filter(status='active', is_temporary=False).prefetch_related( + Prefetch('photos', queryset=ProductKitPhoto.objects.order_by('order')) + ).order_by('name') + + for k in all_kits: + if k.id not in kits_dict: + k.item_type = 'kit' + k.main_photo = k.photos.all()[0] if k.photos.all() else None + kits_dict[k.id] = k # Объединяем и сортируем items = sorted(list(products_dict.values()) + list(kits_dict.values()), key=lambda x: x.name)