Features: 1) Add ordered filtering logic for filter_name methods across products, categories, and brands; 2) Enhance query processing with Case and When operations for precise ordering;

Fixes: 1) Ensure queryset returns `none()` when no valid UUIDs are found in filters;

Extra: 1) Refactor import statements for readability; 2) Clean up and consolidate redundant filter logic across multiple `filter_name` methods;
This commit is contained in:
Egor Pavlovich Gorbunov 2025-06-19 10:49:56 +03:00
parent faaf226c8a
commit 658e799076

View file

@ -3,7 +3,18 @@ import logging
import uuid
from django.core.exceptions import BadRequest
from django.db.models import Avg, Exists, FloatField, OuterRef, Q, Subquery, Value
from django.db.models import (
Avg,
Case,
Exists,
FloatField,
IntegerField,
OuterRef,
Q,
Subquery,
Value,
When,
)
from django.db.models.functions import Coalesce
from django.utils.http import urlsafe_base64_decode
from django.utils.translation import gettext_lazy as _
@ -131,15 +142,19 @@ class ProductFilter(FilterSet):
def filter_name(self, queryset, _name, value):
search_results = process_query(query=value, request=self.request)["products"]
if search_results:
queryset = queryset.filter(
uuid__in=[
result.get("uuid")
for result in search_results
if result.get("uuid") is not None
]
)
return queryset
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
if not uuids:
return queryset.none()
ordering = Case(
*[When(uuid=uuid_, then=pos) for pos, uuid_ in enumerate(uuids)],
output_field=IntegerField(),
)
return (
queryset.filter(uuid__in=uuids).annotate(_order=ordering).order_by("_order")
)
def filter_include_flag(self, queryset, **_kwargs):
if not self.data.get("category_uuid"):
@ -397,15 +412,19 @@ class CategoryFilter(FilterSet):
def filter_name(self, queryset, _name, value):
search_results = process_query(query=value, request=self.request)["categories"]
if search_results:
queryset = queryset.filter(
uuid__in=[
result.get("uuid")
for result in search_results
if result.get("uuid") is not None
]
)
return queryset
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
if not uuids:
return queryset.none()
ordering = Case(
*[When(uuid=uuid_, then=pos) for pos, uuid_ in enumerate(uuids)],
output_field=IntegerField(),
)
return (
queryset.filter(uuid__in=uuids).annotate(_order=ordering).order_by("_order")
)
def filter_whole_categories(self, queryset, _name, value):
has_own_products = Exists(Product.objects.filter(category=OuterRef("pk")))
@ -455,15 +474,19 @@ class BrandFilter(FilterSet):
def filter_name(self, queryset, _name, value):
search_results = process_query(query=value, request=self.request)["brands"]
if search_results:
queryset = queryset.filter(
uuid__in=[
result.get("uuid")
for result in search_results
if result.get("uuid") is not None
]
)
return queryset
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
if not uuids:
return queryset.none()
ordering = Case(
*[When(uuid=uuid_, then=pos) for pos, uuid_ in enumerate(uuids)],
output_field=IntegerField(),
)
return (
queryset.filter(uuid__in=uuids).annotate(_order=ordering).order_by("_order")
)
class FeedbackFilter(FilterSet):