Django查询中values()方法后的计数和最大值
我有一个Django模型:
class Action(models.Model):
id = models.AutoField(primary_key=True)
game = models.ForeignKey(Game)
step = models.ForeignKey(Step)
from_player = models.ForeignKey(Player)
to_player = models.ForeignKey(Player)
type = models.ForeignKey(ActionType)
timestamp = models.DateTimeField(default=timezone.now)
我想做以下几件事:
- 根据游戏、步骤和类型进行筛选
- 找出获得最多操作次数的玩家
为此,我尝试了:
v = Action.objects.filter(game=1, step=2)
v = v.filter(type=3)
v = v.values('to_player').order_by().annotate(count=Count('to_player'))
v = v.annotate(max=Max('count')).filter(count=F('max')) #try to select the max
但是最后一行给我报错(因为第三行返回的是一个字典列表):
Cannot compute Max('count'): 'count' is an aggregate
我知道可能已经有人回答过类似的问题,但Django的values()和aggregate()对我来说有点复杂。我该怎么做才对呢?
2 个回答
0
这个错误给了我们一个提示,你应该用aggregate而不是annotate来获取最大值:
v = Action.objects.filter(game=1, step=2)
v = v.filter(type=3)
v = v.values('to_player').order_by().annotate(count=Count('to_player'))
v = v.aggregate(max=Max('count')).filter(count=F('max')) #try to select the max
我不确定最后的过滤器是否有效,但试试看也没坏处。
3
你可以使用Django的.latest()方法来获取最高的计数。虽然这个方法主要是为日期设计的,但它也可以用在字符串和整数上。
这样你就能找到那个对玩家数量最高的动作:
# combined the filters, no need to separate into two steps
v = Action.objects.filter(game=1, step=2, type=3)
v = v.annotate(count=Count('to_player'))
v = v.latest('count') # will return Action with the highest count