diff --git a/backend/product/views.py b/backend/product/views.py index b2a991b..86dd14b 100644 --- a/backend/product/views.py +++ b/backend/product/views.py @@ -203,24 +203,32 @@ class AllProductsView(APIView): def get(self, request): try: category_slug = request.query_params.get('category') - products = ProductModel.objects.all() + + # Start with optimized base query + products = ProductModel.objects.select_related( + 'category', + 'category__parent' + ).prefetch_related( + 'variants__product_attributes__attribute_type', + 'variants__images', + ) if category_slug: if 'category' not in category_slug: sub_category = get_object_or_404( SubCategoryModel, slug=category_slug) - products = ProductModel.objects.filter( - category=sub_category) + products = products.filter(category=sub_category) else: main_category = get_object_or_404( MainCategoryModel, slug=category_slug) sub_categories = main_category.subcategorys.all() - products = ProductModel.objects.filter( - category__in=sub_categories) + products = products.filter(category__in=sub_categories) + in_stock = request.query_params.get('in_stock') if in_stock is not None: if in_stock.lower() == 'true': - products = products.filter(variants__in_stock__gt=0) + products = products.filter( + variants__in_stock__gt=0).distinct() elif in_stock.lower() != 'false': return Response({'detail': 'in_stock must be "true" or "false".'}, status=status.HTTP_400_BAD_REQUEST) @@ -228,7 +236,8 @@ class AllProductsView(APIView): has_discount = request.query_params.get('has_discount') if has_discount is not None: if has_discount.lower() == 'true': - products = products.filter(variants__discount__gt=0) + products = products.filter( + variants__discount__gt=0).distinct() elif has_discount.lower() != 'false': return Response({'detail': 'has_discount must be "true" or "false".'}, status=status.HTTP_400_BAD_REQUEST) @@ -372,6 +381,16 @@ class ShowCaseProductsView(APIView): def get(self, request): try: category_id = request.query_params.get('slider_category', None) + + # Start with optimized base query + products = ProductModel.objects.select_related( + 'category', + 'category__parent' + ).prefetch_related( + 'variants__product_attributes__attribute_type', + 'variants__images', + ) + if category_id: try: category_id = int(category_id) @@ -381,22 +400,22 @@ class ShowCaseProductsView(APIView): slider_category = get_object_or_404( ShowCaseSlider, pk=category_id) - products = ProductModel.objects.filter( + products = products.filter( variants__slider_category=slider_category).distinct() else: - products = ProductModel.objects.filter( + products = products.filter( variants__slider_category__isnull=False).distinct() # Filter by stock status if `in_stock` is specified in_stock = request.query_params.get('in_stock', "false") == 'true' if in_stock: - products = products.filter(variants__in_stock__gt=0) + products = products.filter(variants__in_stock__gt=0).distinct() # Filter by discount if `has_discount` is specified has_discount = request.query_params.get( 'has_discount', "false") == 'true' if has_discount: - products = products.filter(variants__discount__gt=0) + products = products.filter(variants__discount__gt=0).distinct() # Search filter search_query = request.query_params.get('search', None) @@ -460,8 +479,10 @@ class CommentView(APIView): ) def get(self, request, slug): product = get_object_or_404(ProductModel, slug=slug) + # Optimize comments query to prefetch user data comments = product.comments.filter( - review_status__in=['not_reviwed', 'reviewed_and_confirmed']) + review_status__in=['not_reviwed', 'reviewed_and_confirmed'] + ).select_related('user') paginator = self.pagination_class() paginated_comments = paginator.paginate_queryset(comments, request) comments_ser = self.serializer_class(