微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – Django:按月查询组

如何在不使用额外的情况下按月计算总数?

我目前正在使用:

> django 1.8
> postgre 9.3.13
> Python 2.7

例.

enter image description here

到目前为止我尝试过的.

#Doesn't work for me but I don't mind because I don't want to use extra
truncate_month = connection.ops.date_trunc_sql('month','day')
invoices = Invoice.objects.filter(is_deleted = False,company = company).extra({'month': truncate_month}).values('month').annotate(Sum('total'))

----
#It works but I think that it's too slow if I query a big set of data
for current_month in range(1,13):
    Invoice.objects.filter(date__month = current__month).annotate(total = Sum("total"))

而这一个,答案似乎很好,但我无法导入TruncMonth模块.

Django: Group by date (day, month, year)

附:我知道这个问题已被多次询问,但我没有看到任何答案.

谢谢!

解:

感谢@ Vin-G的回答.

enter image description here

解决方法:

首先,你必须创建一个可以为你提取月份的函数

from django.db import models
from django.db.models import Func

class Month(Func):
    function = 'EXTRACT'
    template = '%(function)s(MONTH from %(expressions)s)'
    output_field = models.IntegerField()

之后你需要做的就是

>用月份注释每一行
>使用值()按注释月份对结果进行分组
>使用Sum()使用总计的总和来注释每个结果

重要提示:如果模型类具有元选项中指定的认顺序,则必须添加空的order_by()子句.这是因为https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#interaction-with-default-ordering-or-order-by

Fields that are mentioned in the order_by() part of a queryset (or which are used in the default ordering on a model) are used when selecting the output data, even if they are not otherwise specified in the values() call. These extra fields are used to group “like” results together and they can make otherwise identical result rows appear to be separate.

如果你不确定,你可以直接添加空的order_by()子句而不会产生任何不利影响.

from django.db.models import Sum

summary = (Invoice.objects
              .annotate(m=Month('date'))
              .values('m')
              .annotate(total=Sum('total'))
              .order_by())

请参见此处的完整要点:https://gist.github.com/alvingonzales/ff9333e39d221981e5fc4cd6cdafdd17

如果您需要更多信息:

有关创建自己的Func类的详细信息:https://docs.djangoproject.com/en/1.8/ref/models/expressions/#func-expressions

有关values()子句的详细信息,(注意它与子句顺序的annotate()交互方式):
https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#values

the order in which annotate() and values() clauses are applied to a query is significant. If the values() clause precedes the annotate(), the annotation will be computed using the grouping described by the values() clause.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐