web-dev-qa-db-fra.com

Modèles Jinja - Formater un flottant en tant que devise séparée par des virgules

J'essaie de formater un flotteur en tant que devise séparée par des virgules. Par exemple. 543921.9354 Devient $543,921.94. J'utilise le filtre format dans les modèles Jinja, qui semble imiter l'opérateur % Dans Python plutôt que Python format une fonction?

Comment puis-je effectuer cette mise en forme dans Jinja? Est-il possible d'utiliser le filtre format? C'est ce que j'ai jusqu'à présent, qui accomplit tout sauf les virgules:

"$%.2f"|format(543921.9354)

ce qui bien sûr donne

$543921.94

37
Kyle Johnson

Écrivez un filtre personnalisé pour cela. Si vous utilisez python 2.7, cela peut ressembler à ceci:

def format_currency(value):
    return "${:,.2f}".format(value)
48
alex vasi

Mise à jour: en utilisant Jinja2 et Python 3, cela fonctionnait très bien dans le modèle sans avoir à définir de code personnalisé:

{{ "${:,.2f}".format(543921.9354) }}

Je ne sais pas exactement quelles sont les dépendances pour que ce travail fonctionne, mais à mon humble avis, toute personne lisant cette réponse ferait bien d'essayer au moins avant de se soucier des filtres personnalisés.

59
biomiker

Pour étendre la réponse de @alex vasi, j'écrirais certainement un filtre personnalisé, mais j'utiliserais également la fonctionnalité locale de python, qui gère le regroupement des devises et le symbole,

def format_currency(value):
    return locale.currency(value, symbol=True, grouping=True)

La principale chose à noter concernant l'utilisation de locale est qu'il ne fonctionne pas avec les paramètres régionaux par défaut 'C', vous devez donc le définir de manière à ce qu'il soit disponible sur votre machine.

Pour ce que vous cherchez, vous avez probablement besoin,

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

mais si vous vouliez des livres sterling, vous utiliseriez,

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'
4
seaders

Python3.6:

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

Filtre global de flacon

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

Filtre global de flacon pour Blueprint

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

Appelez ce filtre global

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

L'appeler dans Jinja sans assigner de filtre global

{{ format('1234567', ',d') }}
#prints 1,234,567
4
Yongju Lee

Si vous avez Python 2.6 ou plus récent:

Vous pouvez écrire un filtre personnalisé dans un seul but, mais, comme solution plus large, vous pouvez également mettre à jour le filtre de format lui-même:

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,
})

Cela remplacera le filtre format existant (à partir de Jinja 2.7.1). La majorité de la fonction a été extraite directement de la source format . La seule différence entre cette fonction et celle de jinja est qu'elle utilise la fonction str.format() pour formater la chaîne.

Voyant que Jinja2 (au moment d'écrire ces lignes) ne prend plus en charge Python 2.5, je parie qu'il ne faudra pas longtemps avant que le filtre format utilise Python str.format() .

3
OozeMeister

Filtre personnalisé à l'aide de Babel (peut également être utilisé pour formater d'autres devises)

Installez Babel ( http://babel.pocoo.org/en/latest/api/numbers.html )

pip install Babel

Filtre Jinja personnalisé

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

Utilisation dans le modèle Jinja:

{{ '-10000.500' | usdollar }}

Output : -$10,000.50