From faaf226c8adcde42ab31d16b13687a5258285206 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Thu, 19 Jun 2025 10:33:34 +0300 Subject: [PATCH] Features: 1) Added `filter_name` method with Elasticsearch-based query processing for `ProductFilter`, `CategoryFilter`, and `BrandFilter`. Fixes: 1) Replaced direct `name` filtering with `filter_name` method in `ProductFilter`, `CategoryFilter`, and `BrandFilter`. Extra: 1) Imported `process_query` from `core.elasticsearch`; 2) Cleaned up unused imports and adjusted formatting. --- core/filters.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/core/filters.py b/core/filters.py index ea2ef71c..bc9929c4 100644 --- a/core/filters.py +++ b/core/filters.py @@ -18,6 +18,7 @@ from django_filters import ( UUIDFilter, ) +from core.elasticsearch import process_query from core.models import Address, Brand, Category, Feedback, Order, Product, Wishlist logger = logging.getLogger(__name__) @@ -47,7 +48,7 @@ class CaseInsensitiveListFilter(BaseInFilter, CharFilter): class ProductFilter(FilterSet): uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID")) - name = CharFilter(field_name="name", lookup_expr="icontains", label=_("Name")) + name = CharFilter(method="filter_name", label=_("Name")) categories = CaseInsensitiveListFilter( field_name="category__name", label=_("Categories") ) @@ -128,6 +129,18 @@ 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 + def filter_include_flag(self, queryset, **_kwargs): if not self.data.get("category_uuid"): raise BadRequest( @@ -350,7 +363,7 @@ class WishlistFilter(FilterSet): class CategoryFilter(FilterSet): uuid = UUIDFilter(field_name="uuid", lookup_expr="exact") - name = CharFilter(field_name="name", lookup_expr="icontains", label=_("Name")) + name = CharFilter(method="filter_name", label=_("Name")) parent_uuid = CharFilter(method="filter_parent_uuid", label=_("Parent")) slug = CharFilter(field_name="slug", lookup_expr="exact", label=_("Slug")) whole = BooleanFilter( @@ -382,6 +395,18 @@ class CategoryFilter(FilterSet): "whole", ] + 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 + def filter_whole_categories(self, queryset, _name, value): has_own_products = Exists(Product.objects.filter(category=OuterRef("pk"))) has_desc_products = Exists( @@ -411,7 +436,7 @@ class CategoryFilter(FilterSet): class BrandFilter(FilterSet): uuid = UUIDFilter(field_name="uuid", lookup_expr="exact") - name = CharFilter(field_name="name", lookup_expr="icontains", label=_("Name")) + name = CharFilter(method="filter_name", label=_("Name")) categories = CaseInsensitiveListFilter( field_name="categories__uuid", lookup_expr="exact", label=_("Categories") ) @@ -428,6 +453,18 @@ class BrandFilter(FilterSet): model = Brand fields = ["uuid", "name"] + 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 + class FeedbackFilter(FilterSet): uuid = UUIDFilter(field_name="uuid", lookup_expr="exact", label=_("UUID"))