Django ORM: Как я могу отфильтровать результаты аннотации - PullRequest
0 голосов
/ 24 мая 2018

У меня есть такая модель:

class Interval(models.Model):
   start = models.Datetime()
   end = models.Datetime(null=True)

Я бы хотел запросить все интервалы, которые превышают 5 минут.Я могу сделать intervals=Interval.objects.exclude(end=None).annotate(d=models.F("end")-models.F("start"))

Когда я делаю intervals[0].d, у меня есть интервал, который является правильным.Теперь я хотел бы получить в качестве результатов только те записи, где d больше 5 минут.

Я пытался intervals=Interval.objects.exclude(end=None).annotate(d=models.F("end")-models.F("start")).filter(d__gt=timedelta(0, 300)), но я получаю следующую ошибку: TypeError: expected string or bytes-like object.Он пытается сопоставить timedelta с регулярным выражением datetime.`

Есть идеи?

Заранее спасибо

1 Ответ

0 голосов
/ 24 мая 2018

Мне кажется, проблема в том, что вы должны указать тип аннотированного столбца для Django как DurationField.Таким образом, вы можете написать это следующим образом:

from datetime import timedelta
from django.db.models import <b>ExpressionWrapper</b>, F, <b>DurationField</b>

delta = <b>ExpressionWrapper(</b>F("end")-F("start")<b>, DurationField())</b>

intervals = (Interval.objects.exclude(end=None)
                             .annotate(d=delta)
                             .filter(d__gt=timedelta(0, 300)))

Это создаст запрос, подобный:

SELECT id, start, end TIMESTAMPDIFF(MICROSECOND, start, end) AS `d`
FROM interval
WHERE TIMESTAMPDIFF(MICROSECOND, start, end) > 300000000

Но мы здесь, таким образом, даем Django подсказку, как интерпретировать поле d (какDurationField) и, таким образом, как " сериализует " объект timedelta).

...