[英]Customize django filter model field
我有以下模型
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中吗?
一种更优雅的方法是创建数据库功能。
假设我们有下面描述的模型。 我们的目标是过滤所有在现在之前结束的对象。
from django.db import models
class SomeModel(models.Model):
date_start = models.DateTimeField()
duration = models.FloatField()
数据库功能实现:
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'
由于以下事实,您建议的查询将因错误而掉落: filter_date
不是模型的字段。
从我的角度来看,您要尝试的是获取具有大于hours
前的some_date的对象。 这是实现以下目的的查询:
some_model.objects.filter(
some_date__gte=datetime.datetime.now()-datetime.timedelta(hours=hours))
您可以使用自定义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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.