【问题标题】:Display and format Django DurationField in template在模板中显示和格式化 Django DurationField
【发布时间】:2016-01-11 08:50:39
【问题描述】:

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

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

是否有任何过滤器或任何其他方式来显示类似的东西

2hours 30 min

【问题讨论】:

  • 我不知道从什么时候开始,但是对于任何搜索这个的人来说,Django 有一个内置的过滤器“timesince”(和 timeuntil),它以一种很好的人类可读格式显示时间增量(例如, “4 天 6 小时”)。在此处查看文档:docs.djangoproject.com/en/3.1/ref/templates/builtins/#timesince

标签: python django duration


【解决方案1】:

不,我认为没有任何内置过滤器可以格式化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)

    

【讨论】:

  • 经过一些小的改动,这是一个完美的答案。谢谢!
【解决方案2】:

对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】:

    这是我使用的,它会循环分钟并仅显示所需的信息:

    @register.filter
    def duration(timedelta):
        """
        Format a duration field
        "2h and 30 min" or only "45 min" for example
    
        :rtype: str
        """
        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 f'{hours}h and {minutes} min'
        elif hours:
            # Display only hours
            return f'{hours}h'
        # Display only minutes
        return f'{minutes} min'
    

    【讨论】:

      【解决方案4】:

      为了使爬虫和屏幕阅读器尽可能阅读,从而提高您的 SEO 评级,最佳做法是使用带有 datetime 属性的 html time 标签。

      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) > 1:
              hours = round(remainder.seconds/3600)
              remainder -= datetime.timedelta(hours=hours)
      
          if round(remainder.seconds/60) > 1:
              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>
      

      【讨论】:

        猜你喜欢
        • 2017-11-15
        • 2013-02-13
        • 2022-11-17
        • 2013-03-05
        • 1970-01-01
        • 2011-10-23
        • 2016-03-23
        • 2010-09-25
        相关资源
        最近更新 更多