8

我正在寻找快速的方法来计算过去 30 天内创建的模型对象,每天分别计算。例如:

27.07.2013 (today) - 3 objects created
26.07.2013 - 0 objects created
25.07.2013 - 2 objects created
...
27.06.2013 - 1 objects created

我将在谷歌图表 API 中使用这些数据。你知道如何有效地获取这些数据吗?

4

2 回答 2

32
items = Foo.objects.filter(createdate__lte=datetime.datetime.today(), createdate__gt=datetime.datetime.today()-datetime.timedelta(days=30)).\
    values('createdate').annotate(count=Count('id'))

这将 (1) 过滤结果以包含过去 30 天,(2) 仅选择 createdate 字段和 (3) 计算 id,按所有选定字段(即 createdate)分组。这将返回以下格式的字典列表:

[
    {'createdate': <datetime.date object>, 'count': <int>},
    {'createdate': <datetime.date object>, 'count': <int>},
    ...
]

编辑:

我不相信有一种方法可以count == 0仅使用 SQL 获取所有日期,即使是带有 的日期。您必须通过 python 代码插入每个缺失的日期,例如:

import datetime

# needed to use .append() later on
items = list(items)

dates = [x.get('createdate') for x in items]

for d in (datetime.datetime.today() - datetime.timedelta(days=x) for x in range(0,30)):
    if d not in dates:
        items.append({'createdate': d, 'count': 0})
于 2013-07-27T07:50:36.610 回答
0

我认为这可以是@knbk 的python 解决方案更优化的解决方案。这具有较少的迭代,并且内部的迭代SET在 py​​thon 中得到了高度优化(在处理和 CPU 周期中)。

from_date = datetime.date.today() - datetime.timedelta(days=7)
orders = Order.objects.filter(created_at=from_date, dealer__executive__branch__user=user)
orders = orders.annotate(count=Count('id')).values('created_at').order_by('created_at')
if len(orders) < 7:
    orders_list = list(orders)
    dates = set([(datetime.date.today() - datetime.timedelta(days=i)) for i in range(6)])
    order_set = set([ord['created_at'] for ord in orders])
    for dt in (order_set - dates):
        orders_list.append({'created_at': dt, 'count': 0})
    orders_list = sorted(orders_list, key=lambda item: item['created_at'])
else:
    orders_list = orders
于 2019-06-28T12:16:20.823 回答