djangoテンプレートで数値をフォーマットする


154

数値をフォーマットしようとしています。例:

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

これはかなり一般的なことですが、どのフィルターを使用するのかわかりません。

編集:これを行う一般的なPythonの方法がある場合は、モデルにフォーマットされたフィールドを追加できます。


3
ターゲットユーザーがヨーロッパにもいる場合は注意してください。ドイツのような一部のヨーロッパの国では、小数点としてを使用します。
tobltobs 2017年

回答:


312

Djangoが提供する人間化アプリケーションはこれを行います:

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

必ずファイルのリストに追加'django.contrib.humanize'してください。INSTALLED_APPSsettings.py


17
これらのいくつかの単純なフィルターが組み込みフィルターの一部ではない理由はありますか?
PawelRoman 2013

8
@PawelRomanめったに使用されない多数のフィルターやタグの読み込みを回避する(テンプレートのレンダリングを高速化する)
Maxime Lorant

INSTALLED_APPSに「django.contrib.humanize」を追加し、テンプレートにも{%load humanize%}を含めて、サーバーを再起動しました。しかし、「intcomma」フィルターを使用しようとすると、次のエラーが表示されます-無効なフィルター: 'intcomma'デバッグトレースは、settings.pyに含まれている「django.contrib.humanize」を示しています。考えられる問題は何でしょうか?
マニッシュ2015年

1
ここで私自身の問題の答えを得ました-(多くのテンプレートで必要なため)ベーステンプレートに{%load humanize%}を含めました。動作していないようです-関連するテンプレートに追加したところ、問題なく動作しました!:-)
マニッシュ

機能しない場合は、ローカライズが原因である可能性があります。その場合は{{my_num | intcomma:False}}を試してください
Jose Cherian


59

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

3
上記のコードのバグ、これを試してください:>>> currency(0.99958) u'$0.00'
Ahsan

1
このコードは、[your_project] / [your_app] / templatetags / [filtername] .pyにある独自のファイルに配置する必要があります。次に、{%load [filtername]%}を使用してテンプレートにロードする必要があります。より役立つ特定の情報については、docs.djangoproject.com / en / 1.10 / howto / custom-template-tagsを参照してください。
マイティパイル2017年

20

settings.pyに次の行を追加してみてください:

USE_THOUSAND_SEPARATOR = True

これはうまくいくはずです。

ドキュメントを参照してください。


2018年4月16日の更新:

これを行うpythonの方法もあります。

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

10
これを使用するときは注意してください。テンプレートに追加するURLやその他の数値もフォーマットします
Christoffer

4
@Christofferのコメントを十分に強調することはできません-IDがレンダリングされてリンクで使用されるテンプレートでは、これが大きな頭痛の種になる可能性があります!
LaundroMat

これはDjangoテンプレートには適していません
Ben

ふさわしくない@ベン?「Pythonの方法」または設定の1000区切りフラグ?桁区切り記号はDjangoテンプレートで適切に機能するはずです。Djangoのバージョンは何ですか?
carton.swing

1
これはテンプレートで直接使用できないため、文字列形式(Python)の方法です。これをテンプレートタグに挿入する必要があります(これは良い答えです)が、これを単に捨てるだけでは完全な答えにはなりません。
ベン

11

ロケールに関与したくない場合は、数値をフォーマットする関数を次に示します。

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)

この関数からカスタムテンプレートフィルターを作成するのは簡単です。


10

ヒューマナイズのウェブサイトが英語であれば解決策は大丈夫です。他の言語については、別のソリューションが必要です。私はBabelの使用をお勧めします。1つの解決策は、数値を適切に表示するカスタムテンプレートタグを作成することです。方法は次のとおりです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パラメータは、現在、私の例で使用されていませんが、私はあなたが簡単にそれをテンプレートコンテキストでだものを使用するには、このテンプレートタグを微調整することができることを示すためにそこにそれを置きます。


1
私のロケールは「pt_BR」で、「intcomma」はブラジルでも「。」で区切られています。「、」ではなく、floatvalue = 25000.35 {{floatvalue | intcomma}}は25000.35
Zokis

正しいですが、この形式は千桁区切り(en_USの場合は25,000.35、fr_FRの場合は25 000,35)に関しては適切ではありません。
MiniQuark、2013年

4

ヒューマナイズアプリの申し出いいと番号をフォーマットする簡単な方法がありますが、カンマで区切り異なるを使用する必要がある場合、それのシンプルなだけで再利用するヒューマナイズアプリからのコードを、区切り文字を交換し、カスタムフィルタを作成します。たとえば、区切り記号としてスペースを使用します

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

ありがとう。私はドットバージョンが必要でした、そしてあなたの提案は私を救いました!乾杯!
kstratis 14

3

少し外れたトピック:

次のように、数値を通貨としてフォーマットする方法を探しているときに、この質問を見つけました。

$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桁で。

たぶん少しハッキーな側面ですが、多分誰かがそれを役に立つと思うでしょう。


2

まあ、私はDjangoの方法を見つけることができませんでしたが、モデル内からpythonの方法を見つけました。

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

うーん-これは-1で、説明はありません-役に立たなかった。答えがどこか間違っていると思う人のために、なぜ回答者と読者のために理由を述べてください。私は、この1つの関数(通貨を取得することによる不快な副作用)でロケールを設定するのが好きではないと思います。これは、-1を説明する可能性があります。
ダニーステープル2012年

前のセクションで説明したように、私は2番目の-1を行いました。コメント、それはs really not correct not giving any reason. Here it簡単です:Djangoは標準のpython関数を許可しない特定のテンプレート(Jinja2に似ている-またはそれのJinja2)を持っています。したがって、この答えはまったく役に立ちません。さらに、Djangoはこれを管理する独自の機能を備えており、機能しているものを新しいものに書き込むことは、あまり良い考えではありません...
tomis

2
私はダウンボーターに同意しません-テンプレートに到達する前に値がビュー関数で適切にフォーマットされていることを確認することは完全に有効なアプローチのようです。
Paul Tomblin 2013

1

ロケールの変更はプロセス全体であり、スレッドセーフではないことに注意してください(つまり、副作用が発生したり、同じプロセス内で実行される他のコードに影響を及ぼしたりする可能性があります)。

私の提案:Babelパッケージをチェックしてください。Djangoテンプレートと統合するいくつかの手段が利用可能です。



1

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.