在Django ORM中将两个字段相乘

4

我该如何执行以下伪代码查询:

CueCompletion.objects.filter(
    user_id=profile_user.pk, status_action_taken_on__gte=day_ago
).sum('amount' * 'opportunities')

基本上,我想要获取上述查询的金额*机会的总和。
2个回答

5

在使用F对象时,您还可以向查询集添加注释。这样,您可以在数据库中执行所有计算,这可能比将所有值提取到列表中并使用Python内存执行列表推导更快。

CueCompletion.objects.filter(
user_id=profile_user.pk, status_action_taken_on__gte=day_ago
).annotate(total=F('amount') * F('opportunities'))

现在你可以通过变量total访问这个值。

这太棒了,我已经寻找这个解决方案超过一个小时了。 - cwhisperer
完美解决方案 - Maha Waqar
从django.db.models导入F。 - pevac

1
一种可能实现它的方法是使用一个名为values_list的Queryset方法。它返回一个特定的查询集(ValuesListQuerySet),然后您可以对其进行进一步的计算。您可以这样做:vqs = CueCompletion.objects.filter(user_id=profile_user.pk, status_action_taken_on__gte=day_ago).values_list('amount','opportunities'),然后您将得到类似于vqs = [(50, 2), (100, 4), (25, 2), ...]的东西,即一个由n个元组组成的列表,每个元组都有amount和opportunities字段的值。(实际上,vqs不是一个列表,而是一个ValuesListQuerySet,但对我们的下一步操作无关紧要)。
我们接下来的操作(即进一步的计算)是:
total = sum(t[0] * t[1] for t in vqs)
在这里,我们使用内置的sum()函数对包含所有(amount * opportunities)结果的生成器进行操作。
(为什么要使用生成器而不是列表推导?请查看this answer!)

你的解决方案真是太棒了,值得获得一枚奖章。 - MiniGunnR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接