Я пытаюсь форматировать числа. Примеры:
1 => 1
12 => 12
123 => 123
1234 => 1,234
12345 => 12,345
Это делается как обычная вещь, но я не могу понять, какой фильтр я должен использовать.
Изменить: если у вас есть общий способ Python для этого, я рад добавить форматированное поле в свою модель.
Django Contributed humanize приложение делает это:
{% load humanize %}
{{ my_num|intcomma }}
Обязательно добавьте 'django.contrib.humanize'
в список INSTALLED_APPS
в файле settings.py
.
Основываясь на других ответах, чтобы распространить это на float, вы можете сделать:
{% load humanize %}
{{ floatvalue|floatformat:2|intcomma }}
Что касается решения Неда Батчелдера, то здесь оно с двумя десятичными знаками и знаком доллара. Это идет где-то как 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'
Если вы не хотите взаимодействовать с локалями, это функция, которая форматирует числа:
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)
Создание настраиваемого фильтра шаблонов из этой функции тривиально.
Попробуйте добавить следующую строку в settings.py:
USE_THOUSAND_SEPARATOR = True
Это должно работать.
Обратитесь к документации.
обновление на 2018-04-16:
Есть также способ Python сделать это:
>>> '{:,}'.format(1000000)
'1,000,000'
Решение 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 %}
Конечно, вы можете использовать переменные:
{% 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 десятичными знаками, если это то, что вы хотите.
Возможно, немного на взломанной стороне, но, возможно, кому-то это будет полезно.
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)
Ну, я не мог найти способ Django, но я нашел путь python изнутри моей модели:
def format_price(self):
import locale
locale.setlocale(locale.LC_ALL, '')
return locale.format('%d', self.price, True)
s really not correct not giving any reason. Here it
просто: у Django есть специальный шаблон (похожий на Jinja2 - или Jinja2), который не поддерживает стандартные функции Python. Так что этот ответ бесполезен вообще. Более того, у Django есть собственные функции, управляющие этим и пишущие что-то новое, что работает, на самом деле не очень хорошая идея ...
На основе ответа 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}" }}
Имейте в виду, что изменение языка является общесистемным, а не потокобезопасным (iow., может иметь побочные эффекты или может влиять на другой код, выполняемый в рамках одного и того же процесса).
Мое предложение: проверьте Babel. Доступны некоторые средства интеграции с шаблонами Django.
Если кто-то наткнулся на это, в Django 2.0.2
вы можете использовать это
Тысяча сепараторов. Обязательно прочтите также локализацию формата.
Не знаю, почему это еще не упоминалось:
{% load l10n %}
{{ value|localize }}
https://docs.djangoproject.com/en/1.11/topics/i18n/formatting/#std:templatefilter-localize
Вы также можете использовать это в своем Django-коде (внешние шаблоны), вызывая localize(number)
.