【问题标题】:Format numbers in django templates在 django 模板中格式化数字
【发布时间】:2010-09-25 16:16:30
【问题描述】:

我正在尝试格式化数字。例子:

1     => 1
12    => 12
123   => 123
1234  => 1,234
12345 => 12,345

这是一件相当常见的事情,但我不知道应该使用哪个过滤器。

编辑:如果您有通用的 Python 方法来执行此操作,我很高兴在我的模型中添加格式化字段。

【问题讨论】:

  • 如果您的目标用户也在欧洲,请小心。一些欧洲国家(如德国)使用 , 作为小数点。

标签: python django


【解决方案1】:

在其他答案的基础上,将其扩展到浮点数,您可以这样做:

{% load humanize %}
{{ floatvalue|floatformat:2|intcomma }}

文档:floatformatintcomma

【讨论】:

    【解决方案2】:

    尝试在 settings.py 中添加以下行:

    USE_THOUSAND_SEPARATOR = True
    

    这应该可行。

    请参阅documentation


    2018 年 4 月 16 日更新:

    还有一种python方法可以做到这一点:

    >>> '{:,}'.format(1000000)
    '1,000,000'
    

    【讨论】:

    • 使用时要小心。还将格式化网址中的数字以及您添加到模板中的其他数字
    • 我怎么强调@Christoffer 的评论都不够——在链接中渲染和使用 id 的模板中,这可能会让人头疼!
    • 这不适用于 Django 模板
    • @Ben 哪个不合适? “python方式”或设置中的千位分隔符标志?千位分隔符标志应该适用于 Django 模板。你的 Django 版本是什么?
    • 字符串格式(python)的方式,因为你不能直接在模板中使用它 - 你必须把它放在模板标签中(这是一个很好的答案),但只是把它扔掉是很少用作完整的答案。
    【解决方案3】:

    关于 Ned Batchelder 的解决方案,这里有 2 个小数点和一个美元符号。这类似于my_app/templatetags/my_filters.py

    from django import template
    from django.contrib.humanize.templatetags.humanize import intcomma
    
    register = template.Library()
    
    def currency(dollars):
        dollars = round(float(dollars), 2)
        return "$%s%s" % (intcomma(int(dollars)), ("%0.2f" % dollars)[-3:])
    
    register.filter('currency', currency)
    

    那你就可以了

    {% load my_filters %}
    {{my_dollars | currency}}
    

    【讨论】:

    • 上面代码的错误,试试这个:>>> currency(0.99958) u'$0.00'
    • 这段代码应该放在自己的文件中,位于 [your_project]/[your_app]/templatetags/[filtername].py。然后应该使用 {% load [filtername] %} 将其加载到模板中。请参阅docs.djangoproject.com/en/1.10/howto/custom-template-tags 了解更多有用和具体的信息。
    【解决方案4】:

    如果有人偶然发现这个,你可以在Django 2.0.2 使用这个

    Thousand separator。请务必阅读format localization

    【讨论】:

      【解决方案5】:

      根据 muhuk 的回答,我做了这个简单的标签封装 python string.format 方法。

      • 在您的应用程序文件夹中创建templatetags
      • 在上面创建一个format.py 文件。
      • 添加这个:

        from django import template
        
        register = template.Library()
        
        @register.filter(name='format')
        def format(value, fmt):
            return fmt.format(value)
        
      • 将其加载到您的模板中{% load format %}
      • 使用它。 {{ some_value|format:"{:0.2f}" }}

      【讨论】:

        【解决方案6】:

        不知道为什么还没有提到这一点:

        {% load l10n %}
        
        {{ value|localize }}
        

        https://docs.djangoproject.com/en/1.11/topics/i18n/formatting/#std:templatefilter-localize

        您也可以通过调用localize(number) 在您的 Django 代码(外部模板)中使用它。

        【讨论】:

          【解决方案7】:

          Django 贡献的humanize 应用程序这样做:

          {% load humanize %}
          {{ my_num|intcomma }}
          

          确保将'django.contrib.humanize' 添加到settings.py 文件中的INSTALLED_APPS 列表中。

          【讨论】:

          • 这几个简单的过滤器不是内置过滤器的一部分有什么原因吗?
          • @PawelRoman 避免加载一堆很少使用的过滤器和标签(从而使模板渲染更快)
          • 我在 INSTALLED_APPS 中添加了 'django.contrib.humanize' 并且还在我的模板中包含了 {% load humanize %} 并重新启动了服务器。但是,当我尝试使用“intcomma”过滤器时,我收到此错误 - 过滤器无效:“intcomma”调试跟踪显示 settings.py 中包含“django.contrib.humanize”。可能是什么问题?
          • 在这里找到了我自己的问题的答案 - 我在基本模板中包含了 {% load humanize %} (因为我需要很多模板)。似乎它不起作用 - 当我在相关模板中添加它时,它运行良好! :-)
          • 如果它不起作用,可能是由于本地化。在这种情况下尝试 {{ my_num|intcomma:False }}
          【解决方案8】:

          有点跑题了:

          我在寻找将数字格式化为货币的方法时发现了这个问题,如下所示:

          $100
          ($50)  # negative numbers without '-' and in parens
          

          我最终做了:

          {% if   var >= 0 %} ${{ var|stringformat:"d" }}
          {% elif var <  0 %} $({{ var|stringformat:"d"|cut:"-" }})
          {% endif %}
          

          你也可以这样做,例如{{ var|stringformat:"1.2f"|cut:"-" }} 显示为 $50.00(如果您愿意,可以保留 2 位小数。

          也许有点老套,但也许其他人会觉得它有用。

          【讨论】:

            【解决方案9】:

            如果您的网站是英文的,humanize 解决方案很好。对于其他语言,您需要另一种解决方案:我建议使用Babel。一种解决方案是创建自定义模板标签以正确显示数字。方法如下:只需在your_project/your_app/templatetags/sexify.py 中创建以下文件:

            # -*- coding: utf-8 -*-
            from django import template
            from django.utils.translation import to_locale, get_language
            from babel.numbers import format_number
            
            register = template.Library()
            
            def sexy_number(context, number, locale = None):
                if locale is None:
                    locale = to_locale(get_language())
                return format_number(number, locale = locale)
            
            register.simple_tag(takes_context=True)(sexy_number)
            

            然后你可以像这样在你的模板中使用这个模板标签:

            {% load sexy_number from sexify %}
            
            {% sexy_number 1234.56 %}
            
            • 对于美国用户(语言环境 en_US),显示 1,234.56。
            • 对于法语用户(区域设置 fr_FR),这将显示 1 234,56。
            • ...

            当然你可以使用变量来代替:

            {% sexy_number some_variable %}
            

            注意:context 参数目前未在我的示例中使用,但我将其放在那里是为了表明您可以轻松调整此模板标签以使其使用模板上下文中的任何内容.

            【讨论】:

            • 我的语言环境是 'pt_BR' 并且 "intcomma" 即使在巴西也可以使用 '.' 分隔。而不是 ',' 是 floatvalue = 25000.35 {{floatvalue|intcomma}} 导致 25000.35
            • 你是对的,但这种格式不适合千位分隔符(en_US 为 25,000.35,fr_FR 为 25,000,35)。
            【解决方案10】:

            humanize app 提供了一种很好且快速的数字格式设置方法,但如果您需要使用不同于逗号的分隔符,只需重复使用 the code from the humanize app、替换分隔符字符和 create a custom filter 即可。例如,使用 空格 作为分隔符:

            @register.filter('intspace')
            def intspace(value):
                """
                Converts an integer to a string containing spaces every three digits.
                For example, 3000 becomes '3 000' and 45000 becomes '45 000'.
                See django.contrib.humanize app
                """
                orig = force_unicode(value)
                new = re.sub("^(-?\d+)(\d{3})", '\g<1> \g<2>', orig)
                if orig == new:
                    return new
                else:
                    return intspace(new)
            

            【讨论】:

            • 谢谢。我需要一个点版本,你的建议救了我!干杯!
            【解决方案11】:

            请注意,更改区域设置是进程范围的,而不是线程安全的(例如,可能会产生副作用或影响在同一进程中执行的其他代码)。

            我的建议:查看Babel 包。一些与 Django 模板集成的方法是可用的。

            【讨论】:

              【解决方案12】:

              如果您不想参与语言环境,这里有一个格式化数字的函数:

              def int_format(value, decimal_points=3, seperator=u'.'):
                  value = str(value)
                  if len(value) <= decimal_points:
                      return value
                  # say here we have value = '12345' and the default params above
                  parts = []
                  while value:
                      parts.append(value[-decimal_points:])
                      value = value[:-decimal_points]
                  # now we should have parts = ['345', '12']
                  parts.reverse()
                  # and the return value should be u'12.345'
                  return seperator.join(parts)
              

              从此函数创建custom template filter 很简单。

              【讨论】:

                【解决方案13】:

                好吧,我找不到 Django 方式,但我确实从我的模型中找到了一种 python 方式:

                def format_price(self):
                    import locale
                    locale.setlocale(locale.LC_ALL, '')
                    return locale.format('%d', self.price, True)
                

                【讨论】:

                • 嗯 - 这已经 -1 了,没有任何解释 - 没有帮助。对于那些认为答案在某些方面不正确的人,为了回答者和读者的利益,请说出原因。我想我不喜欢在这个功能(获取货币的不愉快的副作用)中设置语言环境(这是全球范围内的) - 这可以解释 -1。
                • 我做了第二个 -1 - 如上一页所述。评论,its really not correct not giving any reason. Here its easy:Django 有特定的模板(类似于 Jinja2 - 或者它的 Jinja2),它不允许标准的 python 函数。所以这个答案根本没有用。更重要的是,Django 有自己的函数来管理它并编写任何新的正在工作的东西真的不是一个好主意......
                • 我不同意反对者的观点 - 确保值在视图函数中正确格式化,然后再到达模板似乎是一种完全有效的方法。
                猜你喜欢
                • 1970-01-01
                • 2013-03-05
                • 1970-01-01
                • 2022-08-17
                • 2016-03-23
                • 1970-01-01
                • 2011-08-03
                • 2019-10-03
                相关资源
                最近更新 更多