假设我有这个模型:
class Student(models.Model):
class_name = models.CharField()
mark = models.IntegerField()
我想让所有同班同学中mark
最高的学生。我可以让所有班级中mark
最高的学生像this post中提到的那样。但是我希望所有班级中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
循环相当慢。我不知道是否可以在一行中写下这样的查询?
答案 0 :(得分: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
重命名为mark
{1}}对象。虽然Q
非常方便。