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)