Разделите поле в ответе сериализатора

Это мой сериализатор, и моя проблема заключается в поле average_rating. Оно повторяется во всех экземплярах

class ReviewSerializer(serializers.ModelSerializer):
    average_rating = serializers.SerializerMethodField(read_only=True)
    reviewer = serializers.SerializerMethodField(read_only=True)

    book = serializers.SlugRelatedField(slug_field='title', read_only=True)

    def get_average_rating(self, review):
        book_id = self.context['book_id']
        return Review.objects.filter(book_id=book_id).aggregate(average_rating=Avg('rating'))


    class Meta:
        model = Review
        fields = ["id", "book", "reviewer", "description", 'rating', 'average_rating', ]

что я получаю следующее:

[
    {
        "id": 1,
        "book": "Clean Code: A Handbook of Agile Software Craftsmanship",
        "reviewer": "user1",
        "description": "aaaa",
        "rating": 5,
        "average_rating": {
            "average_rating": 4.5
        }
    },
    {
        "id": 2,
        "book": "Clean Code: A Handbook of Agile Software Craftsmanship",
        "reviewer": "user2",
        "description": "bbbb",
        "rating": 5,
        "average_rating": {
            "average_rating": 4.5
        }
    },
]

но мне нужно вот что: Я не хочу, чтобы average_rating повторялся для всех экземпляров и делал дополнительные запросы. что я могу сделать?

[
 "average_rating": {
            "average_rating": 4.5
        },
    {
        "id": 1,
        "book": "Clean Code: A Handbook of Agile Software Craftsmanship",
        "reviewer": "user1",
        "description": "aaaa",
        "rating": 5,
    },
    {
        "id": 2,
        "book": "Clean Code: A Handbook of Agile Software Craftsmanship",
        "reviewer": "user2",
        "description": "bbbb",
        "rating": 5,
    },
]

Поскольку вы используете SerializerMethodField конкретный запрос будет выполняться с каждым объектом, что не является лучшей практикой.

Вы можете выполнить запрос один раз в представлениях и вернуть его с ответом.

avg = Review.objects.aggregate(average_rating=Avg('rating'))
serializer = ReviewSerializer(query, many=True)
return Response({'average_rating':avg['average_rating'], 'item':serializer.data})
Вернуться на верх