Django - 仅由日期部分组成

时间:2011-03-10 08:30:32

标签: python django django-models django-queryset

MyModel.objects.filter(created_at__gte='2011-03-09', created_at__lte='2011-03-11').values('created_at','status').annotate(status_count=Count('status'))

以上查询存在created_at日期时间字段的问题。是否可以调整上述查询以忽略时间值,并在执行分组时单独使用日期值?

4 个答案:

答案 0 :(得分:11)

我不确定Django的ORM是否可以在查询过程中执行日期时间到日期的转换。但是,您可以先执行查询,获取结果,然后使用Python groupby()函数来排序返回的行。以下是按日期对日期时间进行分组的一个小例子:

from pprint import pprint
from datetime import datetime
from itertools import groupby

rows = [('Frodo party', datetime(3018, 9, 22, 10, 38)),
        ('Nazgul defeat Rangers', datetime(3018, 9, 22, 11, 57)),
        ('Frodo finishes packing', datetime(3018, 9, 23, 10, 59)),
        ('Gandalf tames Shadowfax', datetime(3018, 9, 23, 13, 11)),
        ('Gandalf crosses the Isen', datetime(3018, 9, 24, 18, 46))]

for key, values in groupby(rows, key=lambda row: row[1].date()):
    print('-')
    pprint(key)
    pprint(list(values))

正如您所看到的,您必须为groupby()提供一个key函数,该函数接受它正在分组的对象之一并提取应该进行分组的值 - 在这种情况下,它使用[1]抓取每行中的第二项,然后在其上调用Python datetime方法date(),以提取没有小时和分钟的日期部分。脚本的输出看起来像这样(pprint()函数只是一个用于缩进输出的花哨的“print”语句,在Django代码中不需要它!):

-
datetime.date(3018, 9, 22)
[('Frodo party', datetime.datetime(3018, 9, 22, 10, 38)),
 ('Nazgul defeat Rangers', datetime.datetime(3018, 9, 22, 11, 57))]
-
datetime.date(3018, 9, 23)
[('Frodo finishes packing', datetime.datetime(3018, 9, 23, 10, 59)),
 ('Gandalf tames Shadowfax', datetime.datetime(3018, 9, 23, 13, 11))]
-
datetime.date(3018, 9, 24)
[('Gandalf crosses the Isen', datetime.datetime(3018, 9, 24, 18, 46))]

答案 1 :(得分:6)

我对这个问题来说太迟了,但是为了将来参考,我想指出这实际上可以使用原生Django,如https://stackoverflow.com/a/2283913所述

答案 2 :(得分:2)

是的,可以使用'额外'和DB级日期格式化功能。 实施可以在例如django-qsstats-magic包。

答案 3 :(得分:0)

您可以在django中使用额外的关键字轻松完成。

MyModel.objects
.filter(created_at__gte='2011-03-09', created_at__lte='2011-03-11')
.extra({"created_at":"date_trunc('day', created_at)"}).values('created_at','status').annotate(status_count=Count('status'))

date_trunc是postgres函数,只指定精度。