Đáng buồn thay, nó không phải là một hoạt động khả thi vì (đối với tôi) postgresql WHERE
hoạt động (lọc / loại trừ) thu hẹp các hàng trước khi các hàm tổng hợp có thể hoạt động trên chúng.
Giải pháp duy nhất tôi tìm thấy là chỉ cần tính toán xếp hạng cho tất cả Person
với một bộ truy vấn riêng biệt và sau đó, để chú thích bộ truy vấn của bạn với những kết quả này.
Câu trả lời này (xem phương pháp được cải tiến) giải thích cách "chú thích bộ truy vấn với dữ liệu được chuẩn bị bên ngoài trong một chính tả".
Đây là cách triển khai tôi đã thực hiện cho các mô hình của bạn:
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')))
Tôi đã thử nghiệm nó với Django 2.1.3 và Postgresql 10.5, vì vậy mã có thể thay đổi nhẹ đối với bạn.
Vui lòng chia sẻ phiên bản tương thích với Django 1.11!