【问题标题】:Django convert timedelta to integer in annotationDjango在注释中将timedelta转换为整数
【发布时间】:2019-08-28 11:33:05
【问题描述】:

我正在注释两个日期之间的差异,然后汇总四舍五入的平均值。问题是两个日期之间的差异是datetime.timedelta,所以我得到了错误:

django.db.utils.ProgrammingError: 无法将类型区间转换为数字

如何在Avg() 中使用整数days_to_pay.days

def aggregate_ar_detail(self):
    queryset = self.annotate(
        days_to_pay=Case(
            When(Q(date_paid__isnull=False), then=F('date_paid') - F('date_trans')),
            default=None,
        )
    ).aggregate(
        avg_days=Round(Avg('days_to_pay')),
    )

我尝试在注释上指定输出字段 models.IntegerField() 但这会导致:

TypeError: float() 参数必须是字符串或数字,而不是 'datetime.timedelta'

【问题讨论】:

  • 这里的答案有帮助吗? stackoverflow.com/questions/25646200/… 老实说,我不知道这是不是重复的,所以还没有标记
  • @ggdx 相同的语言和相同的问题,但完全不同的解决方案。更不用说使用.days(来自您的链接的解决方案)包含在我的问题中。

标签: django


【解决方案1】:

设法让它与ExtractDay一起工作

from django.db.models.functions import ExtractDay

def aggregate_ar_detail(self):
    queryset = self.annotate(
        days_to_pay=Case(
            When(Q(date_paid__isnull=False), then=F('date_paid') - F('date_trans')),
            default=None,
        )
    ).aggregate(
        avg_days=Round(Avg(ExtractDay('days_to_pay'))),
    )

【讨论】:

  • 刚刚遇到了类似的问题,我想将持续时间从秒转换为分钟。为了使用提取方法,我必须指定一个输出字段:self.annotate(duration_minutes=ExpressionWrapper(Max('date_time') - Min('date_time'), output_field=DurationField())。我没有运行您的代码,但是您的答案中是否缺少 ExpressionWrapper? (当然也可以是F()-F() 的返回值与Min()-Max() 不同)
猜你喜欢
  • 1970-01-01
  • 2011-07-28
  • 2014-02-20
  • 2023-01-05
  • 2014-10-28
  • 2021-02-04
  • 2010-12-03
  • 2012-05-30
  • 1970-01-01
相关资源
最近更新 更多