Формат чисел в шаблонах Django - PullRequest
       54

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

133 голосов
/ 06 декабря 2008

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

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

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

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

Ответы [ 13 ]

258 голосов
/ 07 декабря 2008

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

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

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

94 голосов
/ 02 июня 2012

Опираясь на другие ответы, вы можете сделать следующее:

{% load humanize %}
{{ floatvalue|floatformat:2|intcomma }}
56 голосов
/ 02 февраля 2010

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

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

USE_THOUSAND_SEPARATOR = True

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

См. документацию .


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

Существует также способ Python сделать эту вещь:

>>> '{:,}'.format(1000000)
'1,000,000'
11 голосов
/ 06 декабря 2008

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

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 голосов
/ 28 февраля 2013

Решение 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 в настоящее время не используется в моем примере, но я поместил его там, чтобы показать, что вы можете легко настроить этот тег шаблона, чтобы он использовал все, что находится в контексте шаблона.

4 голосов
/ 26 января 2012

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

@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)
3 голосов
/ 19 февраля 2014

Немного не по теме:

Я нашел этот вопрос, когда искал способ отформатировать число в валюте, например:

$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 голосов
/ 06 декабря 2008

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

def format_price(self):
    import locale
    locale.setlocale(locale.LC_ALL, '')
    return locale.format('%d', self.price, True)
1 голос
/ 01 июля 2017

На основании ответа Мухука я сделал этот простой метод инкапсуляции тега 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}" }}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...