web-dev-qa-db-fra.com

Comment formater une date dans Jinja2?

Avec Jinja2, comment formater un champ de date? Je sais que dans Python, je peux simplement faire ceci:

print(car.date_of_manufacture.strftime('%Y-%m-%d'))

Mais comment formater la date dans Jinja2?

167
Ambrosio

Il y a deux façons de le faire. L’approche directe consisterait simplement à appeler (et à imprimer) la méthode strftime () dans votre modèle, par exemple

{{ car.date_of_manufacture.strftime('%Y-%m-%d') }}

Une autre approche, nettement meilleure, consisterait à définir votre propre filtre, par exemple:

from flask import Flask
import babel

app = Flask(__name__)

def format_datetime(value, format='medium'):
    if format == 'full':
        format="EEEE, d. MMMM y 'at' HH:mm"
    Elif format == 'medium':
        format="EE dd.MM.y HH:mm"
    return babel.dates.format_datetime(value, format)

app.jinja_env.filters['datetime'] = format_datetime

(Ce filtre est basé sur babel pour des raisons concernant i18n, mais vous pouvez aussi utiliser strftime). L’avantage du filtre est que vous pouvez écrire

{{ car.date_of_manufacture|datetime }}
{{ car.date_of_manufacture|datetime('full') }}

ce qui est plus joli et plus facile à maintenir. Un autre filtre commun est également le filtre "timedelta", qui a pour résultat quelque chose comme "écrit il y a 8 minutes". Vous pouvez utiliser babel.dates.format_timedelta pour cela et l'enregistrer en tant que filtre similaire à l'exemple datetime donné ici.

297
tux21b

Voici le filtre que j'ai fini par utiliser pour strftime dans Jinja2 et Flask

@app.template_filter('strftime')
def _jinja2_filter_datetime(date, fmt=None):
    date = dateutil.parser.parse(date)
    native = date.replace(tzinfo=None)
    format='%b %d, %Y'
    return native.strftime(format) 

Et puis vous utilisez le filtre comme suit:

{{car.date_of_manufacture|strftime}}
19
Raj

Je pense que vous devez écrire votre propre filtre pour cela. C'est en fait l'exemple de filtres personnalisés dans la documentation: http://jinja.pocoo.org/docs/api/#custom-filters

16
Brian Goldman

Si vous traitez avec un objet temporel de niveau inférieur (je n'utilise souvent que des entiers) et que vous ne voulez pas écrire de filtre personnalisé pour une raison quelconque, une approche que j'utilise consiste à transmettre la fonction strftime au modèle en tant que variable, où on peut appeler là où vous en avez besoin.

Par exemple:

import time
context={
    'now':int(time.time()),
    'strftime':time.strftime }  # Note there are no brackets () after strftime
                                # This means we are passing in a function, 
                                # not the result of a function.

self.response.write(jinja2.render_template('sometemplate.html', **context))

Ce qui peut alors être utilisé dans sometemplate.html:

<html>
    <body>
        <p>The time is {{ strftime('%H:%M%:%S',now) }}, and 5 seconds ago it was {{ strftime('%H:%M%:%S',now-5) }}.
    </body>
</html>
13
Olly F-G

Vous pouvez l'utiliser comme ceci dans le modèle sans aucun filtre

{{ car.date_of_manufacture.strftime('%Y-%m-%d') }}
5
Zaytsev Dmitry

Utilisateurs de Google App Engine: si vous passez de Django à Jinja2 et cherchez à remplacer le filtre de date, notez que les codes de mise en forme sont différents.

Les codes% strftime sont ici: http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior

4
Andrew Murphy

en fiole, avec babel, j'aime faire ça:

@app.template_filter('dt')
def _jinja2_filter_datetime(date, fmt=None):
    if fmt:
        return date.strftime(fmt)
    else:
        return date.strftime(gettext('%%m/%%d/%%Y'))

utilisé dans le modèle avec {{mydatetimeobject|dt}}

donc non, avec babel, vous pouvez spécifier vos différents formats dans messages.po, comme par exemple:

#: app/views.py:36
#, python-format
msgid "%%m/%%d/%%Y"
msgstr "%%d/%%m/%%Y"
0
euri10