Optimize product queries with select_related and prefetch_related for improved performance
This commit is contained in:
+33
-12
@@ -203,24 +203,32 @@ class AllProductsView(APIView):
|
|||||||
def get(self, request):
|
def get(self, request):
|
||||||
try:
|
try:
|
||||||
category_slug = request.query_params.get('category')
|
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_slug:
|
||||||
if 'category' not in category_slug:
|
if 'category' not in category_slug:
|
||||||
sub_category = get_object_or_404(
|
sub_category = get_object_or_404(
|
||||||
SubCategoryModel, slug=category_slug)
|
SubCategoryModel, slug=category_slug)
|
||||||
products = ProductModel.objects.filter(
|
products = products.filter(category=sub_category)
|
||||||
category=sub_category)
|
|
||||||
else:
|
else:
|
||||||
main_category = get_object_or_404(
|
main_category = get_object_or_404(
|
||||||
MainCategoryModel, slug=category_slug)
|
MainCategoryModel, slug=category_slug)
|
||||||
sub_categories = main_category.subcategorys.all()
|
sub_categories = main_category.subcategorys.all()
|
||||||
products = ProductModel.objects.filter(
|
products = products.filter(category__in=sub_categories)
|
||||||
category__in=sub_categories)
|
|
||||||
in_stock = request.query_params.get('in_stock')
|
in_stock = request.query_params.get('in_stock')
|
||||||
if in_stock is not None:
|
if in_stock is not None:
|
||||||
if in_stock.lower() == 'true':
|
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':
|
elif in_stock.lower() != 'false':
|
||||||
return Response({'detail': 'in_stock must be "true" or "false".'}, status=status.HTTP_400_BAD_REQUEST)
|
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')
|
has_discount = request.query_params.get('has_discount')
|
||||||
if has_discount is not None:
|
if has_discount is not None:
|
||||||
if has_discount.lower() == 'true':
|
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':
|
elif has_discount.lower() != 'false':
|
||||||
return Response({'detail': 'has_discount must be "true" or "false".'}, status=status.HTTP_400_BAD_REQUEST)
|
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):
|
def get(self, request):
|
||||||
try:
|
try:
|
||||||
category_id = request.query_params.get('slider_category', None)
|
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:
|
if category_id:
|
||||||
try:
|
try:
|
||||||
category_id = int(category_id)
|
category_id = int(category_id)
|
||||||
@@ -381,22 +400,22 @@ class ShowCaseProductsView(APIView):
|
|||||||
slider_category = get_object_or_404(
|
slider_category = get_object_or_404(
|
||||||
ShowCaseSlider, pk=category_id)
|
ShowCaseSlider, pk=category_id)
|
||||||
|
|
||||||
products = ProductModel.objects.filter(
|
products = products.filter(
|
||||||
variants__slider_category=slider_category).distinct()
|
variants__slider_category=slider_category).distinct()
|
||||||
else:
|
else:
|
||||||
products = ProductModel.objects.filter(
|
products = products.filter(
|
||||||
variants__slider_category__isnull=False).distinct()
|
variants__slider_category__isnull=False).distinct()
|
||||||
|
|
||||||
# Filter by stock status if `in_stock` is specified
|
# Filter by stock status if `in_stock` is specified
|
||||||
in_stock = request.query_params.get('in_stock', "false") == 'true'
|
in_stock = request.query_params.get('in_stock', "false") == 'true'
|
||||||
if in_stock:
|
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
|
# Filter by discount if `has_discount` is specified
|
||||||
has_discount = request.query_params.get(
|
has_discount = request.query_params.get(
|
||||||
'has_discount', "false") == 'true'
|
'has_discount', "false") == 'true'
|
||||||
if has_discount:
|
if has_discount:
|
||||||
products = products.filter(variants__discount__gt=0)
|
products = products.filter(variants__discount__gt=0).distinct()
|
||||||
|
|
||||||
# Search filter
|
# Search filter
|
||||||
search_query = request.query_params.get('search', None)
|
search_query = request.query_params.get('search', None)
|
||||||
@@ -460,8 +479,10 @@ class CommentView(APIView):
|
|||||||
)
|
)
|
||||||
def get(self, request, slug):
|
def get(self, request, slug):
|
||||||
product = get_object_or_404(ProductModel, slug=slug)
|
product = get_object_or_404(ProductModel, slug=slug)
|
||||||
|
# Optimize comments query to prefetch user data
|
||||||
comments = product.comments.filter(
|
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()
|
paginator = self.pagination_class()
|
||||||
paginated_comments = paginator.paginate_queryset(comments, request)
|
paginated_comments = paginator.paginate_queryset(comments, request)
|
||||||
comments_ser = self.serializer_class(
|
comments_ser = self.serializer_class(
|
||||||
|
|||||||
Reference in New Issue
Block a user