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:
parent
bb5911abe6
commit
f95f640a06
1 changed files with 27 additions and 24 deletions
|
|
@ -122,6 +122,33 @@ class ProductFilter(FilterSet):
|
||||||
"order_by",
|
"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):
|
def search_products(self, queryset: QuerySet[Product], name, value):
|
||||||
if not value:
|
if not value:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
@ -249,30 +276,6 @@ class ProductFilter(FilterSet):
|
||||||
qs = super().qs
|
qs = super().qs
|
||||||
|
|
||||||
ordering_param = self.data.get("order_by", "")
|
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(
|
qs = qs.annotate(
|
||||||
has_stock=Max(
|
has_stock=Max(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue