在 django 模板中设置数字的格式

我正在试图格式化数字,例如:

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

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

编辑: 如果您有一个通用的 Python 方法来实现这一点,我很乐意在我的模型中添加一个格式化字段。

179940 次浏览

我找不到姜戈的方法,但是我在我的模型里找到了蟒蛇的方法:

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

如果你不想涉及到语言环境,这里有一个格式化数字的函数:

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)

从这个函数创建一个 自定义模板过滤器非常简单。

Django 提供的 人性化应用程序做到了这一点:

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

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

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

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

关于 Ned Batchelder 的解决方案,这里有两个小数点和一个美元符号

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}}

人性化应用程序提供了一种很好的快速格式化数字的方法,但是如果需要使用不同于逗号的分隔符,只需重用 人性化应用程序的代码、替换分隔符字符和 创建自定义过滤器即可。例如,使用 空间作为分隔符:

@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)

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

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

文档: floatformatintcomma

如果你的网站是英文的,人性化解决方案是好的。对于其他语言,您需要另一种解决方案: 我建议使用 巴别塔。一种解决方案是创建一个自定义模板标记来正确显示数字。方法如下: 在 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 %}
  • 对于美国用户(locale en _ US) ,这将显示1,234.56。
  • 对于法国用户(locale fr _ FR) ,这将显示1234,56。
  • ...

当然,你也可以使用变量:

{% sexy_number some_variable %}

注意: context参数目前没有在我的示例中使用,但是我把它放在那里是为了说明您可以轻松地调整这个模板标记,使其使用模板上下文中的任何内容。

稍微跑题了:

我发现这个问题的时候,正在寻找一种将数字格式化为货币的方法,比如:

$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位)。

也许有点粗俗,但也许其他人会觉得有用。

尝试在 setings.py 中添加以下代码行:

USE_THOUSAND_SEPARATOR = True

这个应该可以。

请参阅 文件


更新于2018-04-16:

还有一种蟒蛇式的方法:

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

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

{% load l10n %}


\{\{ value|localize }}

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

您还可以通过调用 localize(number)在 Django 代码(外部模板)中使用这个函数。

基于 muhuk answer 我做了这个简单的标签封装 pythonstring.format方法。

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

    from django import template
    
    
    register = template.Library()
    
    
    @register.filter(name='format')
    def format(value, fmt):
    return fmt.format(value)
    
  • Load it in your template {% load format %}
  • Use it. \{\{ some_value|format:"{:0.2f}" }}

如果有人偶然发现了这一点,在 Django 2.0.2中你可以使用这一点

千分隔符 。一定要读 格式本地化