Я пытаюсь сохранить QuerySet ленивым (не оцененным) при его создании, и цель, которую я имею, - найти последнее событие до заданной даты.
class Event(models.Model):
date_time = models.DateTimeField('Date and time of event')
class Meta:
ordering = ['-date_time']
Теперь у меня есть date_time cut_off, и я могу легко получить все События после этого отключения с помощью:
events = Event.objects.filter(date_time__gte=cut_off)
Теперь я хотел бы включить последнее Событие до cut_offа также!
Я могу придумать несколько способов сделать это, которые вызовут хиты базы данных, но я бы хотел найти решение, которое поддерживает QuerySet ленивым.
Очевидным кандидатом является функция задержки окна.Если мы аннотируем события с помощью date_time следующего события, что-то вроде этого концептуально работает:
window_lag = Window(expression=Lag("date_time"),
order_by=F("date_time").desc())
annotated_events = Event.objects.annotate(date_time_next=window_lag)
events = annotated_events.filter(date_time_next__gte=cut_off)
Но, увы, это недопустимо (пока):
https://code.djangoproject.com/ticket/28333
Это может быть сделано (и я сделал это) с использованием необработанного SQL, но опять же, ой.Я хотел бы сохранить это как можно более чистым, а QuerySet - ленивым (база данных не удастся создать).
Существует ли какой-либо творческий способ написания фильтров, которые не используют оконные функции, могут оставаться ленивыми и при этом достигатьжелаемый результат возврата всех событий после cut_off и непосредственно перед ним?
Мы не знаем, сколько времени прошло между этим событием и датой cut_off, может быть секундами, может быть годами, без предположенийвозможно там, все, что мы знаем, это следующее ... это все.
Возможно, что-то со структурой вроде:
events = Event.objects.filter(Q(date_time__gte=cut_off)|Q(...))
, где второй объект Q как-то творчески добавляет желаемое событие.