【问题标题】:Annotate sum of DateTimeField and IntegerField in Django ORM?在 Django ORM 中注释 DateTimeField 和 IntegerField 的总和?
【发布时间】:2016-10-06 05:28:39
【问题描述】:

给定:

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 转换为某种类型的数据库级持续时间类型,但我无法在文档中找到有关如何执行此操作的线索。

【问题讨论】:

    标签: django django-orm


    【解决方案1】:

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

    对于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/

    【讨论】:

      猜你喜欢
      • 2019-01-22
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-03
      • 2021-01-20
      • 1970-01-01
      • 2017-11-27
      • 2011-08-22
      相关资源
      最近更新 更多