Наборы запросов Django выбирают средний и наилучший результат

#django

#джанго #django

Вопрос:

У меня есть такая модель:

 class Quiz(models.Model):
    user = models.ForeignKey(User, unique=True)
    school_class = models.CharField(max_length=3, choices=klasa_choices)
    points = models.DecimalField(max_digits=5, decimal_places=2,default=0)
    date = models.DateTimeField(null=True,blank=True)
    active = models.BooleanField(default=False)
  

В принципе, я хотел бы получить средний балл (points) и наилучший результат с соответствующим пользователем для каждого school_class . Можно ли это сделать легко? (т. е. без дополнительных вычислений?)

Пока что я пришел к:

 Quiz.objects.values('school_class').annotate(avg=Avg('points'),max=Max('points')).order_by('-avg')
  

но как мне также получить пользователя с лучшим результатом?

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

1. Я не думаю, что это возможно в рамках одного и того же запроса.

2. Как тогда выглядел бы второй запрос? Пока у меня есть Quiz.objects.all().values("user","school_class").order_by('-points') Как мне сделать так, чтобы это возвращало только лучшее?

3. пользователь с максимальным количеством баллов (которые у вас есть из предыдущего запроса) из данного класса Quiz.objects.get(school_class=school_class, points=max) . Однако проблема в том, что их может быть несколько с максимальным количеством баллов, тогда вместо .get() вы должны использовать .filter() .

Ответ №1:

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

 quizzes = Quiz.objects.values('school_class').annotate(avg=Avg('points'),max=Max('points')).order_by('-avg')

Quiz.objects.values('user','school_class').filter(points=quizzes.max)
  

Если вам нужен только один, добавьте .latest(‘дата’), .latest(‘-дата’) или [0], чтобы получить только один.