在Django ORM中注释DateTimeField和IntegerField的总和?

时间:2016-06-06 14:39:15

标签: django django-orm

假设:

from django.conf import settings
from django.db import models

class Membership(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    started = models.DateTimeField()
    num_weeks = models.IntegerField()

如何获取尚未过期的所有成员资格的QuerySet?

我想写这样的东西......

from datetime import datetime, timedelta
Membership.objects.annotate(
    ended=F('started') + datetime.timedelta(weeks=F('weeks'))
).filter(ended__gt=datetime.today())

但是我怀疑F表达式是否与timedeltas兼容,即使它们是,timedelta(weeks=)与F表达式不兼容,所以这段代码失败了。我猜我需要将IntegerField转换为某种类型的数据库级持续时间类型,但我找不到如何在文档中做这样的事情的线索。

1 个答案:

答案 0 :(得分:0)

我今天遇到了这个问题。对于那些寻找答案的人,这里有一个解决方案。

对于 Postgresql,您可以为此使用 INTERVAL 函数。

首先添加一个带有 django Func 类的数据库函数:

class IntervalSeconds(Func):

    function = 'INTERVAL'
    template = "(%(expressions)s * %(function)s '1 weeks')"

然后在您的代码中导入并使用此函数:

Membership.objects.annotate(
    ended=F('started') + IntervalSeconds(F('weeks'))
).filter(ended__gt=datetime.today())

对于天、小时、分钟等其他选项,您可以通过这种方式实现它们,或者您可以自定义此类以在使用时获取类型。

我希望这在 5 年后有所帮助!


参考:https://stackoverflow.com/a/57734565

您可以在此处找到 Postgres INTERVAL:

https://www.postgresql.org/docs/9.1/datatype-datetime.html

https://www.postgresql.org/docs/9.6/functions-datetime.html

另外,你可以看到这个很棒的教程:

https://www.postgresqltutorial.com/postgresql-interval/