基于Django中字段的动态范围过滤器

时间:2014-10-02 09:16:49

标签: django datetime django-queryset

我对Django比较新,还不熟悉Django Querysets。 我想基于字段按日期时间范围过滤查询集。 在MySQL中我会做

WHERE (start_time < NOW() - INTERVAL duration MINUTE)

这里start_time是一个日期时间,持续时间是一个持续时间为分钟的int。

我如何以便携方式在Django中执行此操作?我知道我总是可以使用extra,但我更喜欢它在MySQL和Sqlite3中工作。看起来这些数据库管理器并不共享任何日期时间功能。

1 个答案:

答案 0 :(得分:1)

您可以在查询中使用'F'表达式来引用过滤器表达式中模型的字段(请参阅https://docs.djangoproject.com/en/dev/topics/db/queries/#using-f-expressions-in-filters

这意味着在过滤器中,对于任何特定行,可以说'time_a之前的time_b':

filter(time_a__lt=F('time_b')

然而,出现问题的原因是,根据this related questiontimedelta将不接受动态F()表达式...因此看起来需要自定义SQL。但是,您可以在sqlite和mysql上自动在Django中测试它,以断言它对两者都有效。

同时,避免自定义SQL的特别脏的解决方案是将start_time转换为Unix时间,这使得数学变得容易。

from calendar import timegm
from datetime import timedelta

from django.db import models
from django.db.models import F
from django.utils.timezone import now


class Journey(models.Model):
    name = models.CharField(max_length=64)
    start_time = models.IntegerField()
    duration_minutes = models.IntegerField()


def current_journeys():
    unow = timegm(now().utctimetuple())
    q = Journey.objects.filter(start_time__gt=unow-60*F('duration_minutes'))
    return q.all()