fix product filters
This commit is contained in:
+44
-19
@@ -20,6 +20,7 @@ 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
|
||||
from django.db.models import Min, Max, Value
|
||||
# class APIView(APIView):
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super().__init__(*args, **kwargs)
|
||||
@@ -272,61 +273,85 @@ class AllProductsView(APIView):
|
||||
if in_stock is not None:
|
||||
if in_stock.lower() == 'true':
|
||||
products = products.filter(
|
||||
variants__in_stock__gt=0).distinct()
|
||||
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)
|
||||
return Response(
|
||||
{'detail': 'in_stock must be "true" or "false".'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# Filter by discount
|
||||
# Discount filter
|
||||
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).distinct()
|
||||
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)
|
||||
return Response(
|
||||
{'detail': 'has_discount must be "true" or "false".'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# Search filter
|
||||
# Search
|
||||
search_query = request.query_params.get('search')
|
||||
if search_query:
|
||||
products = products.annotate(
|
||||
similarity=(
|
||||
TrigramSimilarity('name', search_query)
|
||||
+ TrigramSimilarity(Coalesce('description', Value('')), search_query)
|
||||
TrigramSimilarity('name', search_query) +
|
||||
TrigramSimilarity(
|
||||
Coalesce('description', Value('')),
|
||||
search_query
|
||||
)
|
||||
)
|
||||
).filter(similarity__gt=0.1)
|
||||
|
||||
# Price annotation (IMPORTANT for sorting)
|
||||
products = products.annotate(
|
||||
min_price=Min('variants__price'),
|
||||
max_price=Max('variants__price')
|
||||
)
|
||||
|
||||
# Price filters
|
||||
price_gte = request.query_params.get('price_gte')
|
||||
price_lte = request.query_params.get('price_lte')
|
||||
|
||||
products = products.annotate(min_price=Min(
|
||||
'variants__price'), max_price=Max('variants__price'))
|
||||
|
||||
if price_gte:
|
||||
try:
|
||||
price_gte = float(price_gte)
|
||||
products = products.filter(max_price__gte=price_gte)
|
||||
products = products.filter(
|
||||
max_price__gte=float(price_gte)
|
||||
)
|
||||
except ValueError:
|
||||
return Response({'detail': 'price_gte must be a number.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(
|
||||
{'detail': 'price_gte must be a number.'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
price_lte = request.query_params.get('price_lte')
|
||||
if price_lte:
|
||||
try:
|
||||
price_lte = float(price_lte)
|
||||
products = products.filter(min_price__lte=price_lte)
|
||||
products = products.filter(
|
||||
min_price__lte=float(price_lte)
|
||||
)
|
||||
except ValueError:
|
||||
return Response({'detail': 'price_lte must be a number.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Sorting
|
||||
sort_by = request.query_params.get('sort')
|
||||
if sort_by == 'newest':
|
||||
sort_by = '-created_at'
|
||||
elif sort_by == 'oldest':
|
||||
sort_by = 'created_at'
|
||||
if sort_by in ['name', '-name', 'created_at', '-created_at']:
|
||||
products = products.order_by(sort_by)
|
||||
|
||||
elif sort_by in ['price', '-price']:
|
||||
products = products.order_by('min_price' if sort_by == 'price' else '-min_price')
|
||||
elif search_query:
|
||||
products = products.order_by('-similarity', 'name')
|
||||
else:
|
||||
products = products.order_by('name')
|
||||
|
||||
# Pagination
|
||||
products.order_by('category')
|
||||
paginator = self.pagination_class()
|
||||
paginated_products = paginator.paginate_queryset(products, request)
|
||||
serializer = self.serializer_class(
|
||||
|
||||
Reference in New Issue
Block a user