У меня есть следующая структура в моих Django моделях.
ratings.models.py
class Rating(models.Model):
class Meta:
verbose_name = 'Rating'
verbose_name_plural = 'Ratings'
unique_together = [
'user',
'product']
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='user')
product = models.ForeignKey(
Product,
on_delete=models.CASCADE,
related_name='product')
rating = models.PositiveIntegerField(
null=False,
blank=False)
Product
не имеет ничего особенного, чтобы показать здесь. Просто простая Django модель. Я опущу это.
В ProductDetailView в сериализаторах мне нужно рассчитывать по рейтингу. Продукт может быть оценен от 1 до 5. Пример:
{
...
"ratings": {
"rating1_star": 6,
"rating2_star": 5,
"rating3_star": 4,
"rating4_star": 3,
"rating5_star": 3
}
Я добился этого с помощью следующего кода.
class ProductDetailSerializer(serializers.ModelSerializer):
ratings = serializers.SerializerMethodField('get_ratings_detail')
class Meta:
model = Product
fields = [...,'ratings',]
def get_ratings_detail(self, obj):
ratings = Rating.objects.filter(
product=obj)
r_details = ratings.aggregate(
rating1=Count(
'product',
filter=Q(rating__iexact=1)),
rating2=Count(
'product',
filter=Q(rating__iexact=2)),
rating3=Count(
'product',
filter=Q(rating__iexact=3)),
rating4=Count(
'product',
filter=Q(rating__iexact=4)),
rating5=Count(
'product',
filter=Q(rating__iexact=5)),
)
return r_details
У меня вопрос, могу ли я достичь того же результата, используя лучший метод? Мне совсем не нравится, как выглядит get_ratings_detail
, а также я не уверен, что это лучший способ сделать это. Спасибо.