Добавить дополнительное поле в Django QuerySet как тип timedelta - PullRequest
0 голосов
/ 08 февраля 2011

У меня есть следующая модель:

class UptimeManager(models.Manager):
    def with_length(self):
        """Get querySet of uptimes sorted by length including the current one. """
        extra_length = Uptime.objects.extra(select={'length':
            """
            SELECT
                IF (end is null,
                timestampdiff(second,begin,now()),
                timestampdiff(second,begin,end))
            FROM content_uptime c
            WHERE content_uptime.id = c.id
            """
            })
        return extra_length


class Uptime(models.Model):
    begin = models.DateTimeField('beginning')
    end = models.DateTimeField('end', null=True) I call
    host = models.ForeignKey("Host")
    objects = UptimeManager()
    ...

тогда я звоню Uptime.objects.with_length().order_by('-length')[:10], чтобы получить список самых продолжительных простоев.

Но length в шаблоне имеет целочисленный тип. Как изменить мой код, так как длина объекта, возвращаемого менеджером, будет доступна в шаблоне как timedelta объект?

Я почти мог бы сделать это, возвращая список и конвертируя количество секунд в timedelta объекты, но затем я должен выполнить сортировку, фильтрацию и т. Д. В моем коде Python, что довольно неэффективно по сравнению с одним хорошо выполненным SQL-запросом. .

Ответы [ 2 ]

1 голос
/ 08 февраля 2011

Добавьте свойство к модели, которая просматривает фактическое поле и преобразует его в соответствующий тип.

0 голосов
/ 09 февраля 2011

Мое решение состоит в том, чтобы создать фильтр, который определяет тип длины var и возвращает timedelta, если это какой-то целочисленный тип

from django import template
import datetime

register = template.Library()

def timedelta(value):
    if isinstance(value, (long,int)):
        return datetime.timedelta(seconds=value)
    elif isinstance(value, datetime.timedelta):
        return value
    else: raise UnsupportedOperation

register.filter('timedelta',timedelta)

и использовать в шаблоне тривиально {{ uptime.length|timedelta }}

...