Предположим, у меня есть модель 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 сгруппировать только по части даты, а не по всей дате?