From bf0817ed342333bcfff1f7e2f951b427aabb2dcd Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Mon, 3 Nov 2025 11:56:47 +0330 Subject: [PATCH] Optimize product count retrieval and enhance query performance with prefetch_related --- backend/product/serializers.py | 4 +++- backend/product/views.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/backend/product/serializers.py b/backend/product/serializers.py index ef23c8a..ec6d695 100644 --- a/backend/product/serializers.py +++ b/backend/product/serializers.py @@ -102,7 +102,9 @@ class SubCategorySerializer(serializers.ModelSerializer): 'meta_description', 'product_count', 'parent', 'image'] def get_product_count(self, obj): - return obj.products.count() + # Use annotated product_count if available (from optimized query) + # Otherwise fall back to counting (for backward compatibility) + return getattr(obj, 'product_count', obj.products.count()) def get_parent(self, obj): return obj.parent.name diff --git a/backend/product/views.py b/backend/product/views.py index c772ee7..b2a991b 100644 --- a/backend/product/views.py +++ b/backend/product/views.py @@ -14,7 +14,7 @@ from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes from rest_framework.permissions import AllowAny from order.serializers import OrderItemSerailzier from order.models import OrderModel -from django.db.models import Min, Max +from django.db.models import Min, Max, Count, Prefetch from home.models import ShowCaseSlider from home.serializers import ShowCaseSliderSerialzier from order.models import Cart, CartItem @@ -51,7 +51,17 @@ class AllCategories(APIView): # if search_query: # categories = MainCategoryModel.objects.filter(Q(name__icontains=search_query) | Q(slug__icontains=search_query)) # else: - categories = MainCategoryModel.objects.all() + + # Optimize query with prefetch_related to avoid N+1 queries + categories = MainCategoryModel.objects.prefetch_related( + Prefetch( + 'subcategorys', + queryset=SubCategoryModel.objects.annotate( + product_count=Count('products') + ) + ) + ).all() + categories_ser = self.serializer_class( instance=categories, many=True, context={'request': request}) return Response(categories_ser.data, status=status.HTTP_200_OK)