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.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-09-29 11:35:42 +03:00
parent bb5911abe6
commit f95f640a06

View file

@ -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(