В моей модели есть DateTimeField и DurationField с временем, прошедшим с последней записи, вставленной в текущую.Я пытаюсь удалить поле DurationField, но я должен быть в состоянии рассчитать время, прошедшее "на лету" ..
Этот вопрос Разница с предыдущим объектом в аннотации набора запросов django очень похожак моей проблеме.Лучший ответ предполагает использование функции Django Window, представленной в версии 2.0.Я обнаружил, что функция Lead работает только с целыми числами, но у меня есть DateTimeField, а не IntegerField, поэтому я попытался преобразовать / привести свое поле к отметке времени.
Это моя модель:
class Event(models.Model):
date = models.DateTimeField()
time_elapsed = models.DurationField() # TO BE REMOVED
Вот фактический набор запросов:
Event.objects
.annotate(ts=Cast(Extract('date','epoch'),IntegerField()))
.annotate(next_val=Window(
expression=Lead('ts', offset=1,default=0),
order_by=F('date').asc()),
difference=F('next_val')-F('ts'))
Он почти работает (кажется), но он берет следующий объект и делает разницу, в то время как мне нужен PREVIOUS-объект для вычитания текущего.Я не могу найти решение для этого.
Большое спасибо!
ОБНОВЛЕНИЕ
Благодаря @radoh я нашел пропущенную функцию (Lag)К сожалению, я еще не достиг своей цели.
Здесь фактический набор запросов:
qs = Event.objects
.annotate(ts=Cast(Extract('date','epoch'),IntegerField()))
.annotate(prev_ts=Window(expression=Lag('ts',offset=1,default=0),order_by=F('date').asc()),
diff=F('ts')-F('prev_ts'))
Мой diff
теперь является временной дельтой (секундами между событиями) иТеперь я хотел бы исключить события со значением менее 36 часов.Я попытался перейти к прямой фильтрации цепочки () или exclude () к моему QuerySet, но кажется, что не поддерживается: -)
qs.exclude(diff__lt=129600)
ProgrammingError: оконные функциинедопустимо в WHERE
Я обнаружил, что оконные функции не разрешены, но мне интересно, есть ли другой способ сделать то, что я хочу.Есть предложения?
Спасибо