2016-06-28 80 views
1

假設我有這個模型中的所有對象中最大的一個領域的功能:Django的註釋返回具有功能

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

,我想所有的,在具有最高mark學生自己類。在this post中提到的所有課程中,我可以獲得最高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循環是相當緩慢的。我不知道是否可以在一行中編寫這樣的查詢?

回答

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傳遞dictionnary到Q對象之前。而Q(**x)是相當方便。