Python Django Aggregation:仅总和返回值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19138609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django Aggreagtion: Sum return value only?
提问by Stephen
I have a list of values paid and want to display the total paid. I have used Aggregation and Sum to calculate the values together. The problem is,I just want the total value printed out, but aggreagtion prints out: {'amount__sum': 480.0}
(480.0 being the total value added.
我有一个支付的价值列表,想显示支付的总额。我使用 Aggregation 和 Sum 一起计算值。问题是,我只想打印出总价值,但 aggregation 打印出:{'amount__sum': 480.0}
(480.0 是增加的总价值。
In my View, I have:
在我看来,我有:
from django.db.models import Sum
total_paid = Payment.objects.all.aggregate(Sum('amount'))
And to show the value on the page, I have a mako template with the following:
为了在页面上显示值,我有一个 mako 模板,其中包含以下内容:
<p><strong>Total Paid:</strong> ${total_paid}</p>
How would I get it to show 480.0
instead of {'amount__sum': 480.0}
?
我如何让它显示480.0
而不是显示{'amount__sum': 480.0}
?
采纳答案by jproffitt
I don't believe there is a way to get only the value.
我不相信有办法只获得价值。
You could just do ${{ total_paid.amount__sum }}
in your template. Or do total_paid = Payment.objects.all().aggregate(Sum('amount')).get('amount__sum', 0.00)
in your view.
你可以${{ total_paid.amount__sum }}
在你的模板中做。或者total_paid = Payment.objects.all().aggregate(Sum('amount')).get('amount__sum', 0.00)
在你看来。
EDIT
编辑
As others have pointed out, .aggregate()
will always return a dictionary with all of the keys from the aggregates present, so doing .get()
on the result is not necessary. However, if the queryset is empty, each aggregate value would be None
. So depending on your code, if you are expecting a float, you could do:
正如其他人指出的那样,.aggregate()
将始终返回一个字典,其中包含现有聚合中的所有键,因此.get()
没有必要对结果进行处理。但是,如果查询集为空,则每个聚合值将为None
。因此,根据您的代码,如果您期望浮动,您可以执行以下操作:
total_paid = Payment.objects.all().aggregate(Sum('amount'))['amount__sum'] or 0.00
total_paid = Payment.objects.all().aggregate(Sum('amount'))['amount__sum'] or 0.00
回答by nimasmi
The aggregate()
method returns a dictionary. If you know you're only returning a single-entry dictionary you could use .values()[0]
.
该aggregate()
方法返回一个字典。如果你知道你只返回一个单条目字典,你可以使用.values()[0]
.
In Python 2:
在Python 2 中:
total_paid = Payment.objects.aggregate(Sum('amount')).values()[0]
In Python 3, (thanks @lmiguelvargasf) this will need to be:
在Python 3 中,(感谢 @lmiguelvargasf)这将需要是:
total_paid = list(Payment.objects.aggregate(Sum('amount')).values())[0]
The end result is the same as @jproffitt's answer, but it avoids repeating the amount__sum
part, so it's a little more generic.
最终结果与@jprofitt 的答案相同,但它避免了重复该amount__sum
部分,因此它更通用一些。
回答by mehmet
Give it a name and then ask for it:
给它一个名字,然后询问它:
total_paid = Payment.objects.all.aggregate(sum=Sum('amount'))['sum']
Should be little more readable, and there is no need for conversion.
应该更易读一点,并且不需要转换。
回答by lmiguelvargasf
In Python 3:
在 Python 3 中:
You can solve it by converting the dict_values
to a list
:
您可以通过将 the 转换dict_values
为 a来解决它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.
The previous code avoids using 'column_name__sum'
as key, but in case you prefer the dictionary way:
前面的代码避免使用'column_name__sum'
as 键,但如果您更喜欢字典方式:
total_paid = Payment.objects.aggregate(Sum('amount'))['amount__sum'] or 0
In terms of efficiency, I made a test with some data I have, and it seems that using the dictionary key is faster:
在效率方面,我用我手头的一些数据做了一个测试,似乎使用字典键更快:
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)
In terms of readability, I think that @mehmet's solution is the best one, and I have also test its efficiency:
在可读性方面,我认为@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)