在模板中显示和格式化Django DurationField

时间:2015-10-13 14:34:40

标签: python django duration

我使用Django 1.8,我的一个字段定义为DurationField,但我没有找到任何方法在我的模板上正确显示它,如果我这样输出:

{{runtime}}
i just get 0:00:00.007980

是否有任何过滤器或任何其他方式显示更像

的内容
2hours 30 min

4 个答案:

答案 0 :(得分:10)

不,我不认为有任何内置的过滤器可以格式化timedelta,但是自己编写它应该相当容易。

这是一个基本的(未经测试的)示例:

from django import template


register = template.Library()


@register.filter
def duration(td):
    total_seconds = int(td.total_seconds())
    hours = total_seconds // 3600
    minutes = (total_seconds % 3600) // 60

    return '{} hours {} min'.format(hours, minutes)

答案 1 :(得分:0)

这是我使用的那个,它会四舍五入并仅显示所需的信息:

@register.filter
def duration(timedelta):
    """ Format a duration field --> 2h and 30 min or only 45 min """
    total_seconds = int(timedelta.total_seconds())
    hours = total_seconds // 3600
    minutes = round((total_seconds % 3600) / 60)
    if minutes == 60:
        hours += 1
        minutes = 0
    if hours and minutes:
        # Display both
        return '{}h et {} min'.format(hours, minutes)
    elif hours:
        # Display only hours
        return '{}h'.format(hours)
    # Display only minutes
    return '{} min'.format(minutes)

答案 2 :(得分:0)

Aumo答案的贡献:

from django import template


register = template.Library()


@register.filter
def duration(td):

    total_seconds = int(td.total_seconds())

    days = total_seconds // 86400
    remaining_hours = total_seconds % 86400
    remaining_minutes = remaining_hours % 3600
    hours = remaining_hours // 3600
    minutes = remaining_minutes // 60
    seconds = remaining_minutes % 60

    days_str = f'{days}d ' if days else ''
    hours_str = f'{hours}h ' if hours else ''
    minutes_str = f'{minutes}m ' if minutes else ''
    seconds_str = f'{seconds}s' if seconds and not hours_str else ''

    return f'{days_str}{hours_str}{minutes_str}{seconds_str}'

答案 3 :(得分:0)

为了使抓取工具和屏幕阅读器尽可能了解此内容,从而提高您的SEO评分,最佳做法是使用带有time属性的html datetime标签。

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time
https://www.w3.org/TR/2014/REC-html5-20141028/infrastructure.html#valid-duration-string

我写了一个模板标签来完成持续时间的格式化,包括机器形式和人类可读形式。这将显示天,小时,分钟,秒和微秒,并使用最大可能的增量并隐藏任何值为0的值。它还会处理多个标签并根据需要添加逗号和空格。

datetime.py(模板标记文件)

import datetime

from django import template
register = template.Library()
from django.template.defaultfilters import pluralize

@register.filter
def duration(value, mode=""):

    assert mode in ["machine", "phrase", "clock"]

    remainder = value
    response = ""
    days = 0
    hours = 0
    minutes = 0
    seconds = 0
    microseconds = 0

    if remainder.days > 0:
        days = remainder.days
        remainder -= datetime.timedelta(days=remainder.days)

    if round(remainder.seconds/3600) > 0:
        hours = round(remainder.seconds/3600)
        remainder -= datetime.timedelta(hours=hours)

    if round(remainder.seconds/60) > 0:
        minutes = round(remainder.seconds/60)
        remainder -= datetime.timedelta(minutes=minutes)

    if remainder.seconds > 0:
        seconds = remainder.seconds
        remainder -= datetime.timedelta(seconds=seconds)

    if remainder.microseconds > 0:
        microseconds = remainder.microseconds
        remainder -= datetime.timedelta(microseconds=microseconds)

    if mode == "machine":

        response = "P{days}DT{hours}H{minutes}M{seconds}.{microseconds}S".format(
            days=days,
            hours=hours,
            minutes=minutes,
            seconds=seconds,
            microseconds=str(microseconds).zfill(6),
        )

    elif mode == "phrase":
        
        response = []
        if days:
            response.append(
                "{days} day{plural_suffix}".format(
                    days=days, 
                    plural_suffix=pluralize(days),
                )
            )
        if hours:
            response.append(
                "{hours} hour{plural_suffix}".format(
                    hours=hours,
                    plural_suffix=pluralize(hours),
                )
            )
        if minutes:
            response.append(
                "{minutes} minute{plural_suffix}".format(
                    minutes=minutes,
                    plural_suffix=pluralize(minutes),
                )
            )
        if seconds:
            response.append(
                "{seconds} second{plural_suffix}".format(
                    seconds=seconds,
                    plural_suffix=pluralize(seconds),
                )
            )
        if microseconds:
            response.append(
                "{microseconds} microsecond{plural_suffix}".format(
                    microseconds=microseconds,
                    plural_suffix=pluralize(microseconds),
                )
            )

        response = ", ".join(response)

    elif mode == "clock":

        response = []
        if days:
            response.append(
                "{days} day{plural_suffix}".format(
                    days=days, 
                    plural_suffix=pluralize(days),
                )
            )
        if hours or minutes or seconds or microseconds:
            time_string = "{hours}:{minutes}".format(
                hours = str(hours).zfill(2),
                minutes = str(minutes).zfill(2),
            )
            if seconds or microseconds:
                time_string += ":{seconds}".format(
                    seconds = str(seconds).zfill(2),
                )                   
                if microseconds:
                    time_string += ".{microseconds}".format(
                        microseconds = str(microseconds).zfill(6),
                    )

            response.append(time_string)

        response = ", ".join(response)

    return response

template.html(模板文件)

{% load datetime %}
<!-- phrase format -->
<time datetime="{{ event.duration|duration:'machine' }}">
    {{ event.duration|duration:'phrase' }}
</time>

<!-- clock format -->
<time datetime="{{ event.duration|duration:'machine' }}">
    {{ event.duration|duration:'clock' }}
</time>

示例输出

<!-- phrase format -->
<time datetime="P2DT1H0M0.000000S">2 days, 1 hour</time>

<!-- clock format -->
<time datetime="P2DT1H0M0.000000S">2 days, 01:00</time>