Tyvärr är det inte en möjlig operation eftersom (för mig) postgresql WHERE
operation (filtrera/uteslut) begränsar raderna innan aggregeringsfunktionerna kan fungera på dem.
Den enda lösningen jag hittade är att helt enkelt beräkna rankningen för alla Person
med en separat frågeuppsättning och sedan för att kommentera din frågeuppsättning med dessa resultat.
Detta svar (se den förbättrade metoden) förklarar hur man "kommenterar en frågeuppsättning med externt förberedda data i ett diktat".
Här är implementeringen jag gjorde för dina modeller:
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')))
Jag testade det med Django 2.1.3 och Postgresql 10.5, så koden kan ändras lite för dig.
Dela gärna en version som är kompatibel med Django 1.11!