gpt4 book ai didi

django - 注释查询集排名字段的正确方法

转载 作者:行者123 更新时间:2023-11-29 13:12:49 25 4
gpt4 key购买 nike

假设这样的模型:

class Person(models.Model):
name = models.CharField(max_length=20)

class Session(models.Model):
start_time = models.TimeField(auto_now_add=True)
end_time = models.TimeField(blank=True, null=True)
person = models.ForeignKey(Person)

class GameSession(models.Model):
game_type = models.CharField(max_length=2)
score = models.PositiveIntegerField(default=0, blank=True)
session = models.ForeignKey(Session)

我想要一个查询集函数来返回每个人的总分,这是他所有游戏得分和他在所有 session 中花费的所有时间的总和,以及一个人相对于所有人的排名。如下所示:

class DenseRank(Func):
function = 'DENSE_RANK'
template = '%(function)s() Over(Order by %(expressions)s desc)'

class PersonQuerySet(models.query.QuerySet):
def total_scores(self):
return self.annotate(total_score=some_fcn_for_calculate).annotate(rank=DenseRank('total_score'))

我可以找到一种方法来计算总分,但密集排名不是我想要的,因为它只是根据当前查询集中的人计算排名,但我想计算一个人相对于所有人的排名。

我使用 django 1.11 和 postgres 10.5,请给我一个正确的方法来查找查询集中每个人的排名,因为我希望能够在计算 total_score 和排名之前或之后添加另一个过滤器。

最佳答案

遗憾的是,这不是一个可能的操作,因为(对我而言)postgresql WHERE 操作(过滤/排除)在聚合函数可以处理它们之前缩小了行。

我找到的唯一解决方案是使用单独的查询集简单地计算所有 Person 的排名,然后用这些结果注释您的查询集。

This answer (参见改进的方法)解释了如何“在字典中使用外部准备的数据注释查询集”。

这是我为您的模型所做的实现:

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 兼容的版本!

关于django - 注释查询集排名字段的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52735708/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com