2

假设我有这个模型:

class Student(models.Model):
    class_name = models.CharField()
    mark = models.IntegerField()

我想让所有mark班里成绩最高的学生。我可以得到mark所有班级中最高的学生,就像这篇文章中提到的那样。但我希望所有mark 班上成绩最高的学生,像这样:

Student.objects.annotate(
    highest_mark_in_class=Max(
        Students.objects.filter(class_name=F('class_name'))
        .filter(mark=highest_mark_in_class)
    )
)

我可以用一个for循环来做到这一点,但是对于一个大型数据库for循环来说是相当慢的。不知道这样的查询能不能写成一行?

4

1 回答 1

0

您将不得不为此使用 2 个查询:

import operator
from functools import reduce
from django.db.models import Max, Q

best_marks = Student.objects.values('class_name').annotate(mark=Max('mark'))
q_object = reduce(operator.or_, (Q(**x) for x in best_marks))
queryset = Student.objects.filter(q_object)

第一个查询获取每个类别的最佳分数列表。

第二个查询获取标记和班级与列表中的一项匹配的所有学生。

请注意,如果您调用.annotate(best_mark=Max('mark'))而不是,则在将字典传递给对象之前.annotate(mark=Max('mark')),您将不得不做一些额外的工作来重命名best_mark。虽然很方便。markQQ(**x)

于 2016-06-28T12:40:44.337 回答