残念ながら、(私にとっては)postgresql WHERE
なので、これは可能な操作ではありません。 操作(フィルター/除外)は、集計関数が行を処理する前に行を絞り込みます。
私が見つけた唯一の解決策は、すべてのPerson
のランキングを単純に計算することです。 別のクエリセットを使用してから、これらの結果でクエリセットに注釈を付けます。
この回答 (改善された方法を参照)「dictで外部的に準備されたデータでクエリセットに注釈を付ける」方法を説明します。
これが私があなたのモデルのために作った実装です:
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')))
Django2.1.3とPostgresql10.5でテストしたので、コードが少し変わる可能性があります。
Django 1.11と互換性のあるバージョンを自由に共有してください!