Собственный шаблонный фильтр Django: тысячное разделение цифр пробелом

категория: Django
Сегодня будем писать собственный шаблонный фильтр, который будет форматировать денежные суммы в удобочитаемый вид, к примеру: 12938120938.92 станет 12 938 120 938.92 или 12,938,120,938.92 или любой другой разделитель, который можно будет придумать. Фильтр будет работать как для целых чисел, так и для чисел с плавающей точкой. Начнем с того, как создать собственный шаблонный фильтр Django: 1. Создаем в приложении проекта, где этот фильтр будем применять, папку templatetags, в ней __init__.py и питоновский файл, пусть будет filters.py. Пример приложения core:
core/
    models.py
    templatetags/
        __init__.py
        filters.py
    views.py
2. В начале filters.py подключаем библиотеку тегов, где будем регистрировать свой фильтр:
from django import template
#
register = template.Library()
3. Регистрируем свой фильтр, просто обворачивая функцию декоратором @register.filter 4. Подгружаем в шаблон и используем:
{% load filters %}
{{ some_price|price_format }}
Осталось только написать сам фильтр и использовать. Итак, содержание filters.py с подробным описанием:
#! coding: utf-8
from django import template
#
register = template.Library()
#
@register.filter
def price_format(value, seperator=u' '):
    """Форматирует денежные единицы в удобочитаемый вид.
    9837979.67 -> 9 837 979.67
    Работает для целых чисел и чисел с плавающей точкой.
    Аргумент - разделитель, по умолчанию - символ пробела.
    Возвращает строку."""
    # Если число с плавающей точкой
    if isinstance(value, float):
        value = str(value)
        #знаки после целой части
        penny = value[value.find('.'):]
        #целая часть
        value = value[:value.find('.')]
    # Если число целое
    if isinstance(value, int):
        value = str(value)
        penny = ''
    # Если целая часть меньше 3-х символов -
    # то ее разделять не нужно
    if len(value) <= 3:
        return value + penny
    parts = []
    # Выбираем по три символа в список
    while value:
        parts.append(value[-3:])
        value = value[:-3]
    # Сортируем список в обратном порядке
    parts.reverse()
    # Возвращаем результат
    return seperator.join(parts) + penny
Возможно этот фильтр реализовать и по-другому, например используя регулярные выражения или модифицировать, но я особо не парился :) Если кто захочет, предлагайте свои варианты.


blog comments powered by Disqus