我正在寻找快速方法来计算过去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
我将在google charts API中使用此数据。你知道如何有效地获得这些数据吗?
答案 0 :(得分:22)
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>},
...
]
编辑:
我不相信有一种方法可以使用SQL来获取所有日期,即使是那些count == 0
的日期。您必须通过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})
答案 1 :(得分:0)
我认为使用@knbk的python解决方案可以使该解决方案更加优化。它具有较少的迭代,并且SET
内部的迭代在python中得到了高度优化(在处理和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