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.models import ShowCaseSlider
|
||||||
from home.serializers import ShowCaseSliderSerialzier
|
from home.serializers import ShowCaseSliderSerialzier
|
||||||
from order.models import Cart, CartItem
|
from order.models import Cart, CartItem
|
||||||
|
from django.db.models import Min, Max, Value
|
||||||
# class APIView(APIView):
|
# class APIView(APIView):
|
||||||
# def __init__(self, *args, **kwargs):
|
# def __init__(self, *args, **kwargs):
|
||||||
# super().__init__(*args, **kwargs)
|
# super().__init__(*args, **kwargs)
|
||||||
@@ -272,61 +273,85 @@ class AllProductsView(APIView):
|
|||||||
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(
|
products = products.filter(
|
||||||
variants__in_stock__gt=0).distinct()
|
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
|
||||||
|
)
|
||||||
|
|
||||||
# Filter by discount
|
# Discount filter
|
||||||
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(
|
products = products.filter(
|
||||||
variants__discount__gt=0).distinct()
|
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
|
||||||
|
)
|
||||||
|
|
||||||
# Search filter
|
# Search
|
||||||
search_query = request.query_params.get('search')
|
search_query = request.query_params.get('search')
|
||||||
if search_query:
|
if search_query:
|
||||||
products = products.annotate(
|
products = products.annotate(
|
||||||
similarity=(
|
similarity=(
|
||||||
TrigramSimilarity('name', search_query)
|
TrigramSimilarity('name', search_query) +
|
||||||
+ TrigramSimilarity(Coalesce('description', Value('')), search_query)
|
TrigramSimilarity(
|
||||||
|
Coalesce('description', Value('')),
|
||||||
|
search_query
|
||||||
|
)
|
||||||
)
|
)
|
||||||
).filter(similarity__gt=0.1)
|
).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 filters
|
||||||
price_gte = request.query_params.get('price_gte')
|
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:
|
if price_gte:
|
||||||
try:
|
try:
|
||||||
price_gte = float(price_gte)
|
products = products.filter(
|
||||||
products = products.filter(max_price__gte=price_gte)
|
max_price__gte=float(price_gte)
|
||||||
|
)
|
||||||
except ValueError:
|
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:
|
if price_lte:
|
||||||
try:
|
try:
|
||||||
price_lte = float(price_lte)
|
products = products.filter(
|
||||||
products = products.filter(min_price__lte=price_lte)
|
min_price__lte=float(price_lte)
|
||||||
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return Response({'detail': 'price_lte must be a number.'}, status=status.HTTP_400_BAD_REQUEST)
|
return Response({'detail': 'price_lte must be a number.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# Sorting
|
# Sorting
|
||||||
sort_by = request.query_params.get('sort')
|
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']:
|
if sort_by in ['name', '-name', 'created_at', '-created_at']:
|
||||||
products = products.order_by(sort_by)
|
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:
|
elif search_query:
|
||||||
products = products.order_by('-similarity', 'name')
|
products = products.order_by('-similarity', 'name')
|
||||||
else:
|
else:
|
||||||
products = products.order_by('name')
|
products = products.order_by('name')
|
||||||
|
|
||||||
# Pagination
|
# Pagination
|
||||||
products.order_by('category')
|
|
||||||
paginator = self.pagination_class()
|
paginator = self.pagination_class()
|
||||||
paginated_products = paginator.paginate_queryset(products, request)
|
paginated_products = paginator.paginate_queryset(products, request)
|
||||||
serializer = self.serializer_class(
|
serializer = self.serializer_class(
|
||||||
|
|||||||
Reference in New Issue
Block a user