Django ORM:如何基于注释timedelta结果进行过滤

时间:2018-05-24 10:12:52

标签: django orm django-queryset

我有一个这样的模型:

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 :(得分:2)

我认为问题在于您必须将注释列的类型指定为Django DurationField。所以你可以这样写:

from datetime import timedelta
from django.db.models import ExpressionWrapper, F, DurationField

delta = ExpressionWrapper(F("end")-F("start"), DurationField())

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),以及如何“序列化”{{1} } object)。