Почему django.db.models.Avg() не возвращает объект datetime? И почему то, что он возвращает неправильно?

Вот моя модель Джанго:

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. Это поплавок. Почему? Среднее значение DateTimeField должно быть DateTimeField, верно? Так почему же это поплавок? Я даже мог понять строку, но точно не число с плавающей запятой. Это не десятичные числовые данные.

Как только мы решим эту проблему, я смогу разобрать данные из поплавка, чтобы понять, что означает Django. Я вижу, что 20150225, очевидно, означает 26 февраля 2015 года. Но подождите, это означает, что время суток будет представлено 046183.0. Что, черт возьми, это вообще значит? 4:61 и 83 секунды?? Это не имеет никакого смысла.

Может кто-нибудь, пожалуйста, объясните мне все это? Это кажется немного беспорядком.


person Saqib Ali    schedule 26.02.2015    source источник
comment
Каково среднее значение 2 марта 2014 г., 3 сентября 1886 г. и 12 декабря 1949 г.?   -  person    schedule 26.02.2015
comment
@LegoStormtroopr Я думал так: каждая дата и время может быть представлена ​​​​как точка на полуоткрытом отрезке линии с определенной конечной точкой (поэтому ее можно представить в виде числового значения, например, как время, прошедшее с конечной точки, поэтому среднее арифметическое вычислимо ).   -  person inejc    schedule 26.02.2015


Ответы (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)

Что вы можете сделать, так это преобразовать объект datetime в временную метку unix (количество секунд, прошедших с начала 1970 года без високосных секунд) и вычислить среднее значение с помощью метода extra().

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

Я предлагаю вам прочитать это перед преобразованием между объектами unix time и datetime, поскольку вы должны учитывать разницу между наивным и осведомленным дата и время.

person inejc    schedule 26.02.2015
comment
Ваш ответ полезен и приближает меня. Но это создает для меня другие проблемы. В опубликованном вами ответе также есть некоторые синтаксические ошибки. Поэтому я задал аналогичный вопрос здесь: « title = «как написать набор запросов django, который правильно вычисляет среднее значение поля даты и времени wi»> stackoverflow.com/questions/28758714/ - person Saqib Ali; 27.02.2015

Из исходного кода django всегда вернуть float. Похоже, Avg предназначено для использования с числами.

Вы можете попытаться преобразовать возвращенное число с плавающей запятой, используя strptime, Я не пробовал это и не уверен, что возвращаемое число с плавающей запятой является средним значением, которое вы ищете.

person Aziz Alfoudari    schedule 26.02.2015