Значения Django Аннотировать Avg() не группируются должным образом

#django #django-models #django-orm

Вопрос:

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

Моя модель бд является:

 class Review(models.Model):

SCORE_CHOICES = [(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')]

user = models.ForeignKey(get_user_model(), related_name="reviews_by_user", on_delete=models.CASCADE)
recipe = models.ForeignKey(Recipe, related_name="reviews_by_recipe", on_delete=models.CASCADE)
score = models.IntegerField(choices=SCORE_CHOICES)
date_created = models.DateTimeField(default=timezone.now)

def __str__(self):
    return f"{self.user} rated {self.recipe} with {self.score}"

class Meta:
    ordering = ['-date_created']
 

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

 Review.objects.values('recipe').annotate(Avg('score'))
 

в результате я получаю:

 <QuerySet [{'recipe': 1, 'score__avg': 5.0}, {'recipe': 1, 'score__avg': 5.0}, {'recipe': 2, 'score__avg': 4.0}, {'recipe': 2, 'score__avg': 3.0}, {'recipe': 5, 'score__avg': 3.0}, {'recipe': 5, 'score__avg': 2.0}]>
 

Что для меня абсолютно странно. Он должен группировать рецепты, но вместо этого он подсчитывает среднее значение для каждой строки. Я просмотрел документацию по агрегированию Django, но не могу найти никаких ограничений или специальных положений, которые могли бы помочь понять, чего мне не хватает.

Пожалуйста, дайте мне знать, если у кого-нибудь есть представление о том, что происходит.

Ответ №1:

Решено!

.метод order_by() в конце концов «завершает» такую группировку

так:

 Review.objects.values('recipe').annotate(Avg('score')).order_by()
 

Результат:

 <QuerySet [{'recipe': 1, 'score__avg': 5.0}, {'recipe': 2, 'score__avg': 3.5}, {'recipe': 5, 'score__avg': 2.5}]>
 

Комментарии:

1. Не «завершается», скажем, потому, что порядок по умолчанию в вашей модели мешает здесь группе по ( docs.djangoproject.com/en/3.1/topics/db/aggregation/… ). Если вы обновитесь до Django 3.2, этот вызов order_by больше не понадобится.