为什么django.db.models.Avg()不返回日期时间对象?为什么它返回错误?

时间:2015-02-26 09:29:01

标签: python django django-models django-database

这是我的Django模型:

class MyModel(models.Model):
    a = IntegerField()
    b = DateTimeField()

以下是我在此模型上执行的QuerySet,用于查找b的每个值的计数,最小值,最大值和平均值a

>>> MyModel.objects.values('a').annotate(count=Count("b"), min=Min('b'), max=Max('b'), avg=Avg('b'))

{'a': 1, 'count': 2, 
 'avg': 20150226046183.0, 
 'min': datetime.datetime(2015, 2, 26, 1, 8, 22, tzinfo=<UTC>), 
 'max': datetime.datetime(2015, 2, 26, 8, 15, 44, tzinfo=<UTC>)}

查看与avg键关联的值。这是一个浮动。为什么? DateTimeFields的平均值应该是DateTimeField,对吧?那为什么它是所有东西的浮动?我甚至可以理解一个字符串 - 但绝对不是浮点数。这不是十进制数字数据。

一旦我们解决了这个问题,我就可以解析浮点数据,找出Django的含义。我可以看到20150225显然意味着2015年2月26日。但等等,这意味着时间将由046183.0表示。到底是什么意思呢?凌晨4:61和83秒?这毫无意义。

有人可以向我解释这一切吗?这看起来有点乱。

2 个答案:

答案 0 :(得分:2)

从源代码中,Avg总是返回一个浮点数:

class Avg(Aggregate):
    function = 'AVG'
    name = 'Avg'

    def __init__(self, expression, **extra):
        super(Avg, self).__init__(expression, output_field=FloatField(), **extra)

    def convert_value(self, value, expression, connection, context):
        if value is None:
            return value
        return float(value)

你可以做的是将你的日期时间对象转换为unix时间戳(自1970年年初以来经过的秒数,没有闰秒),并使用extra()方法计算平均值。

MyModel.objects.extra('avg': 'AVG(UNIX_TIMESTAMP(b))'.values('avg')

我建议您在转换unix时间和datetime对象之前阅读this,因为您必须考虑天真时间和感知日期时间之间的差异。

答案 1 :(得分:1)

django's source code开始,它始终返回float。看起来Avg的意图与数字一起使用。

您可以尝试使用strptime转换返回的浮点数,我还没试过这个,也不确定返回的浮点数是否是您要查找的平均值。