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:
parent
faaf226c8a
commit
658e799076
1 changed files with 51 additions and 28 deletions
|
|
@ -3,7 +3,18 @@ import logging
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from django.core.exceptions import BadRequest
|
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.db.models.functions import Coalesce
|
||||||
from django.utils.http import urlsafe_base64_decode
|
from django.utils.http import urlsafe_base64_decode
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
@ -131,15 +142,19 @@ class ProductFilter(FilterSet):
|
||||||
|
|
||||||
def filter_name(self, queryset, _name, value):
|
def filter_name(self, queryset, _name, value):
|
||||||
search_results = process_query(query=value, request=self.request)["products"]
|
search_results = process_query(query=value, request=self.request)["products"]
|
||||||
if search_results:
|
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
|
||||||
queryset = queryset.filter(
|
|
||||||
uuid__in=[
|
if not uuids:
|
||||||
result.get("uuid")
|
return queryset.none()
|
||||||
for result in search_results
|
|
||||||
if result.get("uuid") is not None
|
ordering = Case(
|
||||||
]
|
*[When(uuid=uuid_, then=pos) for pos, uuid_ in enumerate(uuids)],
|
||||||
)
|
output_field=IntegerField(),
|
||||||
return queryset
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
queryset.filter(uuid__in=uuids).annotate(_order=ordering).order_by("_order")
|
||||||
|
)
|
||||||
|
|
||||||
def filter_include_flag(self, queryset, **_kwargs):
|
def filter_include_flag(self, queryset, **_kwargs):
|
||||||
if not self.data.get("category_uuid"):
|
if not self.data.get("category_uuid"):
|
||||||
|
|
@ -397,15 +412,19 @@ class CategoryFilter(FilterSet):
|
||||||
|
|
||||||
def filter_name(self, queryset, _name, value):
|
def filter_name(self, queryset, _name, value):
|
||||||
search_results = process_query(query=value, request=self.request)["categories"]
|
search_results = process_query(query=value, request=self.request)["categories"]
|
||||||
if search_results:
|
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
|
||||||
queryset = queryset.filter(
|
|
||||||
uuid__in=[
|
if not uuids:
|
||||||
result.get("uuid")
|
return queryset.none()
|
||||||
for result in search_results
|
|
||||||
if result.get("uuid") is not None
|
ordering = Case(
|
||||||
]
|
*[When(uuid=uuid_, then=pos) for pos, uuid_ in enumerate(uuids)],
|
||||||
)
|
output_field=IntegerField(),
|
||||||
return queryset
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
queryset.filter(uuid__in=uuids).annotate(_order=ordering).order_by("_order")
|
||||||
|
)
|
||||||
|
|
||||||
def filter_whole_categories(self, queryset, _name, value):
|
def filter_whole_categories(self, queryset, _name, value):
|
||||||
has_own_products = Exists(Product.objects.filter(category=OuterRef("pk")))
|
has_own_products = Exists(Product.objects.filter(category=OuterRef("pk")))
|
||||||
|
|
@ -455,15 +474,19 @@ class BrandFilter(FilterSet):
|
||||||
|
|
||||||
def filter_name(self, queryset, _name, value):
|
def filter_name(self, queryset, _name, value):
|
||||||
search_results = process_query(query=value, request=self.request)["brands"]
|
search_results = process_query(query=value, request=self.request)["brands"]
|
||||||
if search_results:
|
uuids = [res["uuid"] for res in search_results if res.get("uuid")]
|
||||||
queryset = queryset.filter(
|
|
||||||
uuid__in=[
|
if not uuids:
|
||||||
result.get("uuid")
|
return queryset.none()
|
||||||
for result in search_results
|
|
||||||
if result.get("uuid") is not None
|
ordering = Case(
|
||||||
]
|
*[When(uuid=uuid_, then=pos) for pos, uuid_ in enumerate(uuids)],
|
||||||
)
|
output_field=IntegerField(),
|
||||||
return queryset
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
queryset.filter(uuid__in=uuids).annotate(_order=ordering).order_by("_order")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FeedbackFilter(FilterSet):
|
class FeedbackFilter(FilterSet):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue