我有以下型号
class some_model(models.Model):
some_date = models.DateTimeField()
hours = models.IntegerField()
获取当前日期
temp_date = datetime.datetime.now()
现在我希望过滤django字段,就像这样
filter_date = some_date + add timedelta(hours)
然后在django过滤器中使用filter_date
some_model.objects.filter(filter_date__gte = temp_date)
以上查询可能在django?
答案 0 :(得分:3)
另一种更优雅的方法是创建数据库功能。
假设我们拥有下面描述的模型。我们的目标是过滤之前结束的所有对象。
from django.db import models
class SomeModel(models.Model):
date_start = models.DateTimeField()
duration = models.FloatField()
DataBase函数实现:
from django.db.models.expressions import Func
from django.db.models import DateTimeField
class Interval(Func):
function = 'INTERVAL'
template = "(%(expressions)s * %(function)s '1 %(phylum)s')"
def __init__(self, expression, phylum, **extra):
output_field = extra.pop('output_field', DateTimeField())
super(Interval, self).__init__(expression, output_field=output_field, phylum=phylum, **extra)
并使用它。作为Interval函数的第一个参数,您可以传递为F('field_name')或Value()或一些Python对象。作为第二个参数,它可以是:'秒','分钟','小时','天'。
objs = (SomeModel.objects.annotate(date_end=F('date_start') + Interval(F('duration'), 'hour')).
filter(date_end__lte=datetime.datetime.now(pytz.utc)))
经测试:Django == 1.8.15,Postgres:9.4.5
此实现仅适用于Postgres,对于另一个DB,您应该覆盖相关方法:'as_postgresql','as_oracle'
答案 1 :(得分:0)
由于事实filter_date
不是模型的字段,因此您建议的查询会出错。
从我的观点来看,您尝试做的事情是获取some_date大于hours
之前的对象。这是实现这一目标的查询:
some_model.objects.filter(
some_date__gte=datetime.datetime.now()-datetime.timedelta(hours=hours))
答案 2 :(得分:0)
您可以使用custom QuerySet
执行此操作。我建议创建自定义过滤器方法,而不是覆盖现有过滤器方法。
更新基于https://stackoverflow.com/a/33916628/3627387
您可以使用extra
class CustomQuerySet(models.QuerySet):
def date_filter(self):
# using
return self.extra(where=["some_date + hours * INTERVAL '1 hour' >= %s"], params=[datetime.now()])
class some_model(models.Model):
some_date = models.DateTimeField()
hours = models.IntegerField()
objects = CustomQuerySet.as_manager()
# And then in your code
some_model.objects.date_filter()