From f95f640a065cc93f8a5940381f803198599a40f1 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Mon, 29 Sep 2025 11:35:42 +0300 Subject: [PATCH] Features: 1) Optimized `__init__` method in filters to handle annotation logic for `rating` and `price` fields, improving query efficiency. Fixes: 1) Removed redundant annotation logic for `rating` and `price` fields from `qs` method, ensuring no duplication and enhancing maintainability. Extra: Reorganized filter logic by consolidating annotation processes into the constructor; eliminated unused code for cleaner and more maintainable structure. --- core/filters.py | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/core/filters.py b/core/filters.py index ed6de1d9..3ac968a1 100644 --- a/core/filters.py +++ b/core/filters.py @@ -122,6 +122,33 @@ class ProductFilter(FilterSet): "order_by", ] + def __init__(self, data=None, queryset=None, *, request=None, prefix=None): + super().__init__(data=data, queryset=queryset, request=request, prefix=prefix) + ordering_param = self.data.get("order_by", "") + if ordering_param: + order_fields = [field.strip("-") for field in ordering_param.split(",")] + if "rating" in order_fields: + feedback_qs = ( + Feedback.objects.filter(order_product__product_id=OuterRef("pk")) + .values("order_product__product_id") + .annotate(avg_rating=Avg("rating")) + .values("avg_rating") + ) + self.queryset = self.queryset.annotate( + rating=Coalesce( + Subquery(feedback_qs, output_field=FloatField()), + Value(0, output_field=FloatField()), + ) + ) + if "price" in order_fields: + self.queryset = self.queryset.annotate( + price_order=Coalesce( + Max("stocks__price"), + Value(0.0), + output_field=FloatField(), + ) + ) + def search_products(self, queryset: QuerySet[Product], name, value): if not value: return queryset @@ -249,30 +276,6 @@ class ProductFilter(FilterSet): qs = super().qs ordering_param = self.data.get("order_by", "") - if ordering_param: - order_fields_no_sign = [field.strip("-") for field in ordering_param.split(",")] - if "rating" in order_fields_no_sign: - feedback_qs = ( - Feedback.objects.filter(order_product__product_id=OuterRef("pk")) - .values("order_product__product_id") - .annotate(avg_rating=Avg("rating")) - .values("avg_rating") - ) - qs = qs.annotate( - rating=Coalesce( - Subquery(feedback_qs, output_field=FloatField()), - Value(0, output_field=FloatField()), - ) - ) - - if ordering_param and any(f.lstrip("-") == "price" for f in ordering_param.split(",")): - qs = qs.annotate( - price_order=Coalesce( - Max("stocks__price"), - Value(0.0), - output_field=FloatField(), - ) - ) qs = qs.annotate( has_stock=Max(