Django 在日期时间上使用整数和日期时间过滤模型

时间:2020-12-31 15:23:19

标签: python django database

我尝试进行查询以选择自指定时间以来修改过的所有对象 这次是 now - max_schedule_delay,其中 max_schedule_delay 是来自对象的数据(参见下面的代码示例)。

我尝试了多种方法……但我来了。也许你能帮我找到办法。

环境

  • python 2.7
  • django 1.11

数据库:Posgresql

示例代码

from django.db import models

class MyObject(models.Model):
    # last modification date
    mtime = models.DateTimeField(auto_now=True, db_index=True)
    # maximum delay before rescheduling in seconds
    max_schedule_delay = models.IntegerField()

我想要达到的目标

select * from MyObject where (mtime + max_schedule_delay > now)

我的测试

from django.db.models import F, ExpressionWrapper,, TimeField, DateTimeField
from django.db.models.functions import Cast
import datetime

now = datetime.datetime.now()

MyObject.objects.filter(max_schedule_delay__lte=now - F("mtime")) # here max_schedule_delay is a integer, so this query is not possible

# I try to split this query in two, but still not wotking
MyObject.objects.annotate(threshold=ExpressionWrapper(now - F("max_schedule_delay"), output_field=DateTimeField())).filter(mtime__gte=F("threshold"))

MyObject.objects.annotate(threshold=ExpressionWrapper(F("mtime") + F("max_schedule_delay"), output_field=DateTimeField())).filter(threshold__gte=now)

MyObject.objects.annotate(as_date=Cast("max_schedule_delay", TimeField()))

欢迎任何帮助, 谢谢!

1 个答案:

答案 0 :(得分:0)

经过更多研究,基于帖子 Using dateadd in django filter 我能够做一些事情,但仅限于 posgresql

from django.db.models import Func, DateTimeField
import datetime

class DateAdd(Func):
    """
    Custom Func expression to add date and int fields as day addition
    Usage:
    Model.objects.annotate(annotation=DateAdd('field_date','field_seconds'))
    """
    arg_joiner = " + CAST("
    template = "%(expressions)s || ' seconds' as INTERVAL)"
    output_field = DateTimeField()

MyModel.objects.annotate(
        threshold=DateAdd("mtime", "max_schedule_delay")
    ).filter(
        max_schedule_delay__isnull=False,
        state=botSession.STATE.DONE,
        threshold__lte=datetime.datetime.now()
    )