अफसोस की बात है कि पोस्टग्रेस्क्ल WHERE
के बाद से (मेरे लिए) यह एक संभावित ऑपरेशन नहीं है ऑपरेशन (फ़िल्टर/बहिष्कृत) पंक्तियों को संक्षिप्त करता है इससे पहले कि एकत्रीकरण कार्य उन पर काम कर सकें।
एकमात्र समाधान जो मैंने पाया वह है सभी Person
. के लिए रैंकिंग की गणना करना एक अलग क्वेरीसेट के साथ और फिर, इन परिणामों के साथ अपने क्वेरीसेट को एनोटेट करने के लिए।
यह जवाब (बेहतर विधि देखें) बताता है कि कैसे "एक डिक्टेट में बाहरी रूप से तैयार डेटा के साथ एक क्वेरीसेट को एनोटेट करें"।
आपके मॉडलों के लिए मैंने जो कार्यान्वयन किया है वह यहां दिया गया है:
class PersonQuerySet(models.QuerySet):
def total_scores(self):
# compute the global ranking
ranks = (Person.objects
.annotate(total_score=models.Sum('session__gamesession__score'))
.annotate(rank=models.Window(expression=DenseRank(),
order_by=models.F('total_score').decs()))
.values('pk', 'rank'))
# extract and put ranks in a dict
rank_dict = dict((e['pk'], e['rank']) for e in ranks)
# create `WHEN` conditions for mapping filtered Persons to their Rank
whens = [models.When(pk=pk, then=rank) for pk, rank in rank_dict.items()]
# build the query
return (self.annotate(rank=models.Case(*whens, default=0,
output_field=models.IntegerField()))
.annotate(total_score=models.Sum('session__gamesession__score')))
मैंने इसे Django 2.1.3 और Postgresql 10.5 के साथ परीक्षण किया, ताकि कोड आपके लिए हल्के ढंग से बदल सके।
Django 1.11 के साथ संगत संस्करण साझा करने के लिए स्वतंत्र महसूस करें!