Skip to content

Commit

Permalink
Make the annotated rating field in Product and round it in Serializer…
Browse files Browse the repository at this point in the history
…MethodField
  • Loading branch information
earlinn committed Dec 22, 2023
1 parent 4d2cb6b commit 090d484
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
14 changes: 7 additions & 7 deletions backend/api/products_serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.db.models import Avg
from drf_spectacular.utils import extend_schema_field
from drf_yasg.utils import swagger_serializer_method
from rest_framework import serializers
Expand All @@ -17,7 +16,7 @@
Tag,
)

NO_RATING_MESSAGE = "У данного продукта еще нет оценок."
RATING_DECIMAL_PLACES = 1


class SubcategoryLightSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -208,12 +207,13 @@ def get_promotion_quantity(self, obj) -> int:
def get_final_price(self, obj) -> float:
return obj.final_price

# TODO: make annotate
def get_rating(self, obj) -> float:
product_reviews = obj.reviews.all()
if product_reviews:
return round(product_reviews.aggregate(Avg("score"))["score__avg"], 1)
return NO_RATING_MESSAGE
"""Rounds and returns the annotated rating value."""
return (
round(obj.rating, RATING_DECIMAL_PLACES)
if obj.rating is not None
else obj.rating
)


class ProductCreateSerializer(ProductSerializer):
Expand Down
17 changes: 11 additions & 6 deletions backend/api/products_views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.db import transaction
from django.db.models import Avg
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django_filters import rest_framework as rf_filters
Expand Down Expand Up @@ -504,9 +505,11 @@ class ProductViewSet(DestroyWithPayloadMixin, viewsets.ModelViewSet):
"""Viewset for products."""

http_method_names = ["get", "post", "patch", "delete"]
queryset = Product.objects.select_related(
"category", "subcategory", "producer"
).prefetch_related("components", "tags", "promotions", "reviews")
queryset = (
Product.objects.select_related("category", "subcategory", "producer")
.prefetch_related("components", "tags", "promotions", "reviews")
.annotate(rating=Avg("reviews__score"))
)
serializer_class = ProductSerializer
permission_classes = [IsAdminOrReadOnly]
filter_backends = [rf_filters.DjangoFilterBackend]
Expand All @@ -523,9 +526,11 @@ def get_serializer_class(self):
return ProductSerializer

def get_queryset(self):
return Product.objects.select_related(
"category", "subcategory", "producer"
).prefetch_related("components", "tags", "promotions", "reviews")
return (
Product.objects.select_related("category", "subcategory", "producer")
.prefetch_related("components", "tags", "promotions", "reviews")
.annotate(rating=Avg("reviews__score"))
)

@transaction.atomic
def create_delete_or_scold(self, model, product, request):
Expand Down

0 comments on commit 090d484

Please sign in to comment.