【问题标题】:Django manager with datetime.timedelta object inside F query combined with annotate and filterF查询中带有datetime.timedelta对象的Django管理器与注释和过滤器相结合
【发布时间】:2019-05-24 16:51:14
【问题描述】:

我正在尝试在我的应用程序中创建管理器方法,以过滤已在 5/10/15 分钟或任何时间创建的电子邮件对象,从现在开始计数。

虽然我将使用 annotate 创建新参数,它将是 bool 并且他的状态取决于简单的除法减法并检查结果是否大于 0。

from django.db.models import F
from django.utils import timezone


delta = 60 * 1 * 5
current_date = timezone.now()
qs = self.annotate(passed=((current_date - F('created_at')).seconds // delta > 0)).filter(passed=True)

Atm 我的错误说:
AttributeError: 'CombinedExpression' object has no attribute 'seconds'

很明显,((current_date - F('created_at')) 的计算结果不是 datetime.timedelta 对象,而是 CombinedExpression 对象。

我看到了更多问题,即如何将表达式与 0 进行比较?

无论如何,如果我接近实现我的目标或者我这个查询背后的整个逻辑不正确,我将不胜感激任何提示

【问题讨论】:

    标签: django python-3.x django-managers


    【解决方案1】:

    好吧,我设法找到了解决方案,尽管它可能不是优雅的解决方案,但它确实有效

    qs = self.annotate(foo=Sum(current_date - F('created_at'))).filter(foo__gt=Sum(timezone.timedelta(seconds=delta)))

    【讨论】:

      【解决方案2】:

      为什么不这样:

      time_cut_off = timezone.now() - timezone.timedelta(minutes=delta)
      qs = self.filter(created_at__gte=time_cut_off)
      

      这将为您提供在最后 delta 分钟内创建的消息。或者您在哪里查找 5 分钟前创建的消息(如果这是问题,您如何定义)。

      【讨论】:

        【解决方案3】:

        如果您的 timedelta 是常量,文档会提供 a simple and elegant solution

        对于日期和日期/时间字段,您可以添加或减去 timedelta 对象。以下将返回在发布后超过 3 天修改的所有条目:

        >>> from datetime import timedelta
        >>> Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))
        

        在你的情况下,我认为你甚至不需要 F() 对象。

        【讨论】:

        猜你喜欢
        • 2019-12-07
        • 2012-04-05
        • 2013-05-02
        • 2018-06-19
        • 2022-01-14
        • 2016-06-09
        • 1970-01-01
        • 2011-06-04
        • 1970-01-01
        相关资源
        最近更新 更多