我有一个已付款的值列表,并希望显示已付款总额。我使用Aggregation和Sum来一起计算值。问题是,我只想打印出总值,但是聚合打印出来:{'amount__sum': 480.0}
(480.0是总增值。
在我看来,我有:
from django.db.models import Sum
total_paid = Payment.objects.all.aggregate(Sum('amount'))
为了显示页面上的值,我有一个mako模板,其中包含以下内容:
<p><strong>Total Paid:</strong> ${total_paid}</p>
如何让它显示480.0
而不是{'amount__sum': 480.0}
?
答案 0 :(得分:30)
我不相信有办法只获得价值。
您可以在模板中执行${{ total_paid.amount__sum }}
。或者在您的视图中total_paid = Payment.objects.all().aggregate(Sum('amount')).get('amount__sum', 0.00)
。
修改强>
正如其他人所指出的,.aggregate()
将始终返回一个字典,其中包含来自聚合的所有键,因此不需要对结果执行.get()
。但是,如果查询集为空,则每个聚合值都为None
。因此,根据您的代码,如果您期望浮动,您可以这样做:
total_paid = Payment.objects.all().aggregate(Sum('amount'))['amount__sum'] or 0.00
答案 1 :(得分:17)
aggregate()
方法返回字典。如果您知道自己只返回单项词典,则可以使用.values()[0]
。
在 Python 2 :
中total_paid = Payment.objects.aggregate(Sum('amount')).values()[0]
在 Python 3 中,(感谢@lmiguelvargasf),这将需要:
total_paid = list(Payment.objects.aggregate(Sum('amount')).values())[0]
最终结果与@ jproffitt的答案相同,但它避免重复amount__sum
部分,因此它更通用。
答案 2 :(得分:15)
给它起个名字,然后要求它:
total_paid = Payment.objects.all.aggregate(sum=Sum('amount'))['sum']
应该更具可读性,并且不需要转换。
答案 3 :(得分:1)
在Python 3中:
您可以将dict_values
转换为list
:
total_paid = list(Payment.objects.aggregate(Sum('amount')).values())[0] or 0 # the or 0 is required in case the query is an empty query set.
之前的代码避免使用'column_name__sum'
作为键,但如果您更喜欢字典方式:
total_paid = Payment.objects.aggregate(Sum('amount'))['amount__sum'] or 0
在效率方面,我用一些数据进行了测试,似乎使用字典键更快:
In [9]: %timeit total = Pledge.objects.filter(user=user, group__isnull=True).aggregate(Sum('amount'))['amount__sum'] or 0
3.13 ms ± 25.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [10]: %timeit total = list(Pledge.objects.filter(user=user, group__isnull=True).aggregate(Sum('amount')).values())[0] or 0
3.22 ms ± 61.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
在可读性方面,我认为@mehmet的解决方案是最好的,我也测试了它的效率:
In [18]: %timeit Pledge.objects.filter(user=user, group__isnull=True).aggregate(sum=Sum('amount'))['sum'] or 0
3.22 ms ± 124 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
答案 4 :(得分:0)
(仅在使用十进制字段时才有用) 将键值存储在新变量中,如果使用的是小数,则将其转换为浮点数。我认为这是最简单的方法
total_paid = Payment.objects.all.aggregate(Sum('amount'))
# output: {'amount__sum':Decimal('0000.000000')
tp=total_paid['amount__sum']
new_total_paid=float(tp)
答案 5 :(得分:0)
您可以通过此技术 100% 解决您的需求
from django.db.models import Sum
sum_count = Payment.objects.aggregate(Sum('amount'))
totalAmonut = sum_count['Qty__sum']