22

我无法让我的 django 模板一致地显示 timedelta 对象。我尝试在我的模板中使用时间过滤器,但这样做时没有显示任何内容。如果我使用 Assert False,则 timedelta 对象在错误页面上显示如下:

time    datetime.timedelta(0, 38, 132827)

这将时间差显示为:

0:00:38.132827

我只想显示每个 timedelta 对象的小时、分钟和秒。有人对我如何做到这一点有任何建议吗?

4

6 回答 6

9

我按照彼得的建议编写了一个自定义模板过滤器。

这是我采取的步骤。

首先,我按照本指南创建了一个自定义模板过滤器。

请务必阅读本节关于代码布局的内容。

这是我的过滤器代码

from django import template

register = template.Library()

@register.filter()
def smooth_timedelta(timedeltaobj):
    """Convert a datetime.timedelta object into Days, Hours, Minutes, Seconds."""
    secs = timedeltaobj.total_seconds()
    timetot = ""
    if secs > 86400: # 60sec * 60min * 24hrs
        days = secs // 86400
        timetot += "{} days".format(int(days))
        secs = secs - days*86400

    if secs > 3600:
        hrs = secs // 3600
        timetot += " {} hours".format(int(hrs))
        secs = secs - hrs*3600

    if secs > 60:
        mins = secs // 60
        timetot += " {} minutes".format(int(mins))
        secs = secs - mins*60

    if secs > 0:
        timetot += " {} seconds".format(int(secs))
    return timetot

然后在我的模板中我做了

{% load smooth_timedelta %}

{% timedeltaobject|smooth_timedelta %}

示例输出

在此处输入图像描述

于 2017-10-25T09:03:32.360 回答
3

您可以尝试从 timedelta 对象中删除微秒,然后再将其发送到模板:

time = time - datetime.timedelta(microseconds=time.microseconds)
于 2015-05-05T13:50:03.173 回答
2

我认为没有内置任何东西,并且 timedeltas 不会直接公开它们的小时和分钟值。但这个包包含一个可能有帮助的 timedelta 自定义过滤器标签:http: //pydoc.net/django-timedeltafield/0.7.10/

于 2013-05-02T21:41:52.333 回答
0

据我所知,您必须为此编写自己的模板标签。下面是我根据 Django 核心 timesince/timeuntil 代码编写的代码,它应该输出你所追求的:

@register.simple_tag
def duration( duration ):
"""
Usage: {% duration timedelta %}
Returns seconds duration as weeks, days, hours, minutes, seconds
Based on core timesince/timeuntil
"""

    def seconds_in_units(seconds):
    """
    Returns a tuple containing the most appropriate unit for the
    number of seconds supplied and the value in that units form.

    >>> seconds_in_units(7700)
    (2, 'hour')
    """

        unit_totals = OrderedDict()

        unit_limits = [
                       ("week", 7 * 24 * 3600),
                       ("day", 24 * 3600),
                       ("hour", 3600),
                       ("minute", 60),
                       ("second", 1)
                        ]

        for unit_name, limit in unit_limits:
            if seconds >= limit:
                amount = int(float(seconds) / limit)
                if amount != 1:
                    unit_name += 's' # dodgy pluralisation
                unit_totals[unit_name] = amount
                seconds = seconds - ( amount * limit )

        return unit_totals;


if duration:
    if isinstance( duration, datetime.timedelta ):
        if duration.total_seconds > 0:
            unit_totals = seconds_in_units( duration.total_seconds() )
            return ', '.join([str(v)+" "+str(k) for (k,v) in unit_totals.iteritems()])

return 'None'
于 2013-05-02T21:39:10.697 回答
0
from datetime import datetime

start = datetime.now()

taken = datetime.now() - start

str(taken)

'0:03:08.243773'

str(taken).split('.')[0]

'0:03:08'
于 2016-09-29T08:29:12.840 回答
0

编写自己的自定义模板标签的建议是 100% 正确的方法。您将拥有完全的控制权,并且可以随意格式化它。但是——如果你很懒,想要一个使用内置 django 工具的快速解决方案,你可以使用内置的timesince标签来使用 hackey 技术。

基本上,从当前时间中减去您的 timedelta 并将其放入您的模板中。例如

import datetime
import django.template

tdelta = datetime.timedelta(hours=5, minutes=10)
tm = datetime.datetime.utcnow() - tdelta

django_engine = django.template.engines['django']
template = django_engine.from_string("My delta {{ tm|timesince }}")
print(template.render({'tm': tm})

执行上面的代码,./manage.py shell输出为:

My delta 5 hours, 10 minutes
于 2020-09-25T21:02:27.200 回答