【发布时间】:2020-04-23 09:17:15
【问题描述】:
假设我有模型EventDateTime,它有一个页面外键和一个日期字段。即页面可以有多个不同日期和时间的EventDateTime:
模型代码大致如下:
class EventDateTime(Orderable):
page = ParentalKey("Event", on_delete=models.CASCADE, related_name="dates")
date = models.DateTimeField(null=False, blank=False)
# Some other unrelated fields
class Event(Page):
# Some unrelated fields
该网站的运作方式是,它将在特定时间内向用户显示一定数量的事件(例如 10 个),而忽略同一天发生的多次事件(但不会跨越多天)。基本上这个 SQL 查询:
SELECT page_id, DATE(MIN(date))
FROM eventdatetime
WHERE (date >= '2020-01-05 17:45:48.545123')
GROUP BY page_id, DATE(date)
ORDER BY date
LIMIT 10;
例如可以返回:
page_id | date
---------+------------
296 | 2020-01-07
301 | 2020-01-07
298 | 2020-01-09
289 | 2020-01-10
266 | 2020-01-11
267 | 2020-01-11
268 | 2020-01-11
269 | 2020-01-11
54 | 2020-01-13
290 | 2020-01-13
但是,我无法弄清楚如何将这个确切的意图转换为 Django 的 ORM:
EventDateTime.objects\
.filter(page__live=True,date__gte=datetime.now())\
.values('page_id')\
.annotate(Min('date__date')).order_by('date')
这是返回的 SQL:
SELECT "web_eventdatetime"."page_id",
MIN("web_eventdatetime"."date") AS "date__date__min"
FROM "web_eventdatetime"
INNER JOIN "web_event" ON ("web_eventdatetime"."page_id" = "web_event"."page_ptr_id")
INNER JOIN "wagtailcore_page" ON ("web_event"."page_ptr_id" = "wagtailcore_page"."id")
WHERE ("web_eventdatetime"."date" >= 2020-01-05 18:07:57.516323 AND "wagtailcore_page"."live" = True)
GROUP BY "web_eventdatetime"."page_id",
"web_eventdatetime"."date" <-- does not extract date portion
ORDER BY "web_eventdatetime"."date" ASC
请注意,由于某种原因,Django 在倒数第二行中如何不理解我按DATE(MIN(date)) 而不是MIN(date) 分组的意图(不幸的是,这在这种情况下有所不同)。 :(
我如何告诉 Django 只按日期部分而不是整个日期时间进行分组?
【问题讨论】:
-
你能显示你的型号代码吗?
-
这里看起来像
date__gte=datetime.now()你需要date__gte=datetime.now().date()。 -
@funnydman 很好 :) 虽然这取决于我是否展示了今天早些时候发生的事件(两种情况都存在)。无论哪种方式,它仍然不会更改查询的
GROUP BY部分,该部分由date而不是MIN(DATE(date))聚合,就像我试图完成的那样
标签: sql django postgresql django-models group-by