Estoy tratando de formatear un flotante como una moneda separada por comas. Por ejemplo, 543921.9354
convierte en $543,921.94
. Estoy usando el filtro de format
en las plantillas de Jinja, que parece imitar al operador %
en Python en lugar de a la función de format
Python.
¿Cómo puedo lograr este formato en Jinja? ¿Es posible usar el filtro de format
? Esto es lo que tengo hasta ahora, que logra todo excepto las comas:
"$%.2f"|format(543921.9354)
que por supuesto cede
$543921.94
Escribe un filtro personalizado para eso. Si está usando python 2.7, puede verse así:
def format_currency(value): return "${:,.2f}".format(value)
Actualización: Al usar Jinja2 y Python 3, esto funcionó bastante bien en la plantilla sin tener que definir ningún código personalizado:
{{ "${:,.2f}".format(543921.9354) }}
No estoy seguro de cuáles son exactamente las dependencias para que funcione, pero IMO, cualquier otra persona que lea esta respuesta haría bien en al menos intentarlo antes de preocuparse por los filtros personalizados.
Para extender la respuesta de @alex vasi, definitivamente escribiría un filtro personalizado, pero también usaría la propia funcionalidad de locale
python, que maneja la agrupación de monedas, y el símbolo,
def format_currency(value): locale.currency(value, symbol=True, grouping=True)
Lo más importante a tener en cuenta al usar la locale
es que no funciona con la configuración regional predeterminada ‘C’, por lo que debe configurarlo para que esté disponible en su máquina.
Para lo que buscas, probablemente necesites,
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
pero si quisieras libras esterlinas, usarías,
locale.setlocale(locale.LC_ALL, 'en_GB.UTF_8')
.
import locale locale.setlocale(locale.LC_ALL, 'en_US') locale.currency(543921.94, symbol=True, grouping=True) > '$543,921.94' locale.setlocale(locale.LC_ALL, 'en_GB') > '£543,921.94'
def numberFormat(value): return format(int(value), ',d')
@app.template_filter() def numberFormat(value): return format(int(value), ',d')
@app.app_template_filter() def numberFormat(value): return format(int(value), ',d')
{{ '1234567' | numberFormat }} #prints 1,234,567
{{ format('1234567', ',d') }} #prints 1,234,567
Si tienes Python 2.6 o más nuevo:
Podría escribir un filtro personalizado para un propósito, pero, como una solución más amplia, también podría actualizar el filtro de formato en sí mismo:
from jinja import Environment, FileSystemLoader def format(fmt_str, *args, **kwargs): if args and kwargs: raise jinja2.exceptions.FilterArgumentError( "can't handle positional and keyword " "arguments at the same time" ) ufmt_str = jinja2.utils.soft_unicode(fmt_str) if kwargs: return ufmt_str.format(**kwargs) return ufmt_str.format(*args) env = Environment(loader=FileSystemLoader('./my/template/dir')) env.filters.update({ 'format': format, })
Esto reemplazará el filtro de format
existente (a partir de Jinja 2.7.1). La mayoría de la función fue arrancada directamente desde la fuente del format
. La única diferencia entre esta función y la de jinja es que utiliza la función str.format()
para formatear la cadena.
Al ver que Jinja2 (en el momento de escribir esto) ya no es compatible con Python 2.5, apuesto a que no pasará mucho tiempo antes de que el filtro de format
utilice el format
de str.format()
de Python str.format()
.
Filtro personalizado usando Babel (también puede usarse para formatear otras monedas)
Instale Babel ( http://babel.pocoo.org/en/latest/api/numbers.html )
pip install Babel
Filtro Jinja personalizado
from babel.numbers import format_currency @app.template_filter() def usdollar(value): return format_currency(value, 'USD', locale='en_US') app.jinja_env.filters['usdollar'] = usdollar
Uso en Plantilla Jinja:
{{ '-10000.500' | usdollar }} Output : -$10,000.50