Plantillas Jinja – Formatear un flotante como moneda separada por comas

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' 

Python3.6:

 def numberFormat(value): return format(int(value), ',d') 

Filtro global del matraz

 @app.template_filter() def numberFormat(value): return format(int(value), ',d') 

Frasco de filtro global para Blueprint

 @app.app_template_filter() def numberFormat(value): return format(int(value), ',d') 

Llama a este filtro global.

 {{ '1234567' | numberFormat }} #prints 1,234,567 

Llamándolo en Jinja sin asignar un filtro global

 {{ 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