Форматирование чисел в шаблонах django

Я пытаюсь форматировать числа. Примеры:

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

Это делается как обычная вещь, но я не могу понять, какой фильтр я должен использовать.

Изменить: если у вас есть общий способ Python для этого, я рад добавить форматированное поле в свою модель.

Ответ 1

Django Contributed humanize приложение делает это:

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

Обязательно добавьте 'django.contrib.humanize' в список INSTALLED_APPS в файле settings.py.

Ответ 2

Основываясь на других ответах, чтобы распространить это на float, вы можете сделать:

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

Ответ 3

Что касается решения Неда Батчелдера, то здесь оно с двумя десятичными знаками и знаком доллара. Это идет где-то как 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}}

Ответ 4

Если вы не хотите взаимодействовать с локалями, это функция, которая форматирует числа:

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)

Создание настраиваемого фильтра шаблонов из этой функции тривиально.

Ответ 5

Попробуйте добавить следующую строку в settings.py:

USE_THOUSAND_SEPARATOR = True

Это должно работать.

Обратитесь к документации.


обновление на 2018-04-16:

Есть также способ Python сделать это:

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

Ответ 6

Решение 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 %}
  • Для американского пользователя (locale en_US) отображается 1,234,56.
  • Для французского пользователя (locale fr_FR) это отображает 1 234,56.
  • ...

Конечно, вы можете использовать переменные:

{% sexy_number some_variable %}

Примечание: параметр context в настоящее время не используется в моем примере, но я поставил его там, чтобы показать, что вы можете легко настроить этот тег шаблона, чтобы он использовал все, что в контексте шаблона.

Ответ 7

humanize app предлагает хороший и быстрый способ форматирования числа, но если вам нужно использовать разделитель, отличный от запятой, это просто просто повторно использовать код из приложения humanize, замените разделитель char и создать настраиваемый фильтр. Например, используйте пробел как разделитель:

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

Ответ 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

Ну, я не мог найти способ Django, но я нашел путь python изнутри моей модели:

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

Ответ 10

Имейте в виду, что изменение языка является общесистемным, а не потокобезопасным (iow., может иметь побочные эффекты или может влиять на другой код, выполняемый в рамках одного и того же процесса).

Мое предложение: проверьте Babel. Доступны некоторые средства интеграции с шаблонами Django.

Ответ 11

На основе ответа 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}" }}