From c2bbe1b8ec529ee7dccccd7213b008465d3bd776 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Mon, 18 May 2026 14:42:15 +0330 Subject: [PATCH] comment rate added to serilizer and user detail added too --- backend/product/serializers.py | 20 ++++++++++++++++++++ backend/product/views.py | 24 +++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/backend/product/serializers.py b/backend/product/serializers.py index d1e5d65..adf2ece 100644 --- a/backend/product/serializers.py +++ b/backend/product/serializers.py @@ -3,6 +3,7 @@ from rest_framework import serializers from django.utils import timezone from datetime import timedelta from django.contrib.auth.models import AnonymousUser +from account.models import User class DetailSerializer(serializers.ModelSerializer): @@ -323,12 +324,31 @@ class DynamicProductSerializer(serializers.ModelSerializer): return serializer.data +class UserCommentSerializer(serializers.ModelSerializer): + """Lightweight user serializer for comment author info""" + class Meta: + model = User + fields = ['id', 'first_name', 'last_name', 'profile_photo', 'phone'] + + class CommentSerializer(serializers.ModelSerializer): + user = UserCommentSerializer(read_only=True) + user_rating = serializers.SerializerMethodField() + class Meta: model = CommentModel exclude = ('review_status', ) read_only_fields = ('review_status', 'product', 'user') + def get_user_rating(self, obj): + """ + Get user's rating for this product using cached data to avoid N+1 queries. + The cache is provided by the CommentView.get() method. + """ + user_ratings_cache = self.context.get('user_ratings_cache', {}) + # O(1) lookup in cache instead of database query + return user_ratings_cache.get(obj.user_id) + class BotProductSerializer(serializers.ModelSerializer): class Meta: diff --git a/backend/product/views.py b/backend/product/views.py index e40327a..3bfe627 100644 --- a/backend/product/views.py +++ b/backend/product/views.py @@ -590,8 +590,30 @@ class CommentView(APIView): ).select_related('user') paginator = self.pagination_class() paginated_comments = paginator.paginate_queryset(comments, request) + + # OPTIMIZATION: Fetch all user ratings in a single query + # Get user IDs from paginated comments to only fetch ratings for displayed comments + user_ids = [comment.user_id for comment in paginated_comments] + + # Single query to get all ratings for these users on this product + user_ratings = ProductRating.objects.filter( + product=product, + user_id__in=user_ids + ).values_list('user_id', 'rating') + + # Build cache dictionary for O(1) lookups in serializer + user_ratings_cache = {user_id: rating for user_id, rating in user_ratings} + + # Pass cache to serializer context to avoid N queries comments_ser = self.serializer_class( - instance=paginated_comments, many=True) + instance=paginated_comments, + many=True, + context={ + 'request': request, + 'user_ratings_cache': user_ratings_cache, + 'product': product + } + ) return paginator.get_paginated_response(comments_ser.data) def post(self, request, slug):