繁体   English   中英

自定义Django过滤器模型字段

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM