如何编写 Django 查询,在作为 PostGres SQL 执行时执行日期数学运算?

Dav*_*ave 4 django postgresql datetime python-3.x

我正在使用 Django 和 Python 3.7。我正在编写一个在 PostGres 9.4 db 上运行的 Django 查询,但无法弄清楚如何形成我的表达式包装器,以便我向现有日期列添加秒数(整数)。我尝试了下面的

hour_filter = ExtractHour(ExpressionWrapper(
            F("article__created_on") + timedelta(0,
                                                 F("article__websitet__avg_time_in_seconds_to_reach_ep")),
            output_field=models.DateTimeField)
        ),
)
Run Code Online (Sandbox Code Playgroud)

但我收到错误

unsupported type for timedelta seconds component: F
Run Code Online (Sandbox Code Playgroud)

有什么想法可以重写我的 ExpressionWrapper 以在 PostGres 查询中进行日期数学运算吗?

编辑; 以下是模型和相关字段...

class Website(models.Model):
    ...
    avg_time_in_seconds_to_reach_ep = models.FloatField(default=0, null=True)


class Article(models.Model):
    objects = ArticleManager()
    website = models.ForeignKey(Website, on_delete=models.CASCADE, related_name='articlesite')
Run Code Online (Sandbox Code Playgroud)

Iai*_*ton 5

您可以向 Django 添加数据库函数,为此您可以在 postgres 中为INTERVAL 语句添加一个函数

class IntervalSeconds(Func):

    function = 'INTERVAL'
    template = "(%(expressions)s * %(function)s '1 seconds')"
Run Code Online (Sandbox Code Playgroud)

然后,您可以在查询中使用此函数向日期时间添加秒数

YourModel.objects.annotate(
    attr=ExpressionWrapper(
        F("article__created_on") + IntervalSeconds(F("article__websitet__avg_time_in_seconds_to_reach_ep")),
        output_field=models.DateTimeField()
    ),
)
Run Code Online (Sandbox Code Playgroud)

IntervalSeconds函数的输出是 1 秒的Postgres 间隔乘以传递给它的字段。可以将其与时间戳相加或相减。你可以做一个通用的Interval不只需要几秒钟的通用函数,这有点复杂

需要ExpressionWrapper将结果转换为日期时间对象