Django - 仅包含日期部分的分组

发布于 2024-10-21 07:57:48 字数 259 浏览 4 评论 0原文

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 日期时间字段存在问题。是否可以调整上述查询以在执行分组依据时忽略时间值并单独使用日期值?

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

The above query has the problem with the created_at datetime field. Is it possible to tune the above query to ignore the time value and use the date value alone while performing group by?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

壹場煙雨 2024-10-28 07:57:48

我不确定 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))]

I am not sure whether Django's ORM can perform a conversion of datetimes to dates in the middle of a query. You could, though, do the query first, get the results, then use the Python groupby() function to sort out the rows that are returned. Here is a small example of grouping datetimes by date:

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))

As you can see, you have to provide groupby() with a key function that takes one of the objects that it is grouping and extracts the value by which the grouping should take place — in this case, it grabs the second item in each row with [1] and then calls the Python datetime method date() on it to extract the date part without the hours and minutes. The output of the script looks like this (the pprint() function is just a fancy "print" statement that indents the output, it won't be needed in your Django code!):

-
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))]
生活了然无味 2024-10-28 07:57:48

我回答这个问题已经太晚了,但为了将来的参考,我想指出,这实际上可以通过本机 Django 实现,如 https 中所述://stackoverflow.com/a/2283913

I'm too late for this question, but for future reference, I want to point out that this is actually possible with native Django, as described at https://stackoverflow.com/a/2283913

情栀口红 2024-10-28 07:57:48

是的,使用“额外”和数据库级日期格式化函数可以实现这一点。
可以在例如 django-qsstats-magic 包中找到实现。

Yes, that's possible using 'extra' and DB-level date formatting functions.
Implementation can be found in e.g. django-qsstats-magic package.

只是在用心讲痛 2024-10-28 07:57:48

您可以使用 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 函数,仅指定精度。

You can do it easily using extra keyword in 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 is postgres function it takes, only precision specified.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文