Wie formatiere ich ein Datum in Jinja2?


182

Wie formatiere ich mit Jinja2 ein Datumsfeld? Ich weiß, dass ich in Python einfach Folgendes tun kann:

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

Aber wie formatiere ich das Datum in Jinja2?

Antworten:


322

Es gibt zwei Möglichkeiten, dies zu tun. Der direkte Ansatz wäre beispielsweise, einfach die strftime () -Methode in Ihrer Vorlage aufzurufen (und zu drucken)

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

Ein anderer, deutlich besserer Ansatz wäre, einen eigenen Filter zu definieren, z.

from flask import Flask
import babel

app = Flask(__name__)

@app.template_filter()
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)

(Dieser Filter basiert aus Gründen in Bezug auf i18n auf babel, aber Sie können auch strftime verwenden). Der Vorteil des Filters ist, dass Sie schreiben können

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

Das sieht besser aus und ist wartbarer. Ein weiterer gebräuchlicher Filter ist auch der "timedelta" -Filter, der so etwas wie "vor 8 Minuten geschrieben" ergibt. Sie können dies verwenden babel.dates.format_timedeltaund als Filter registrieren, ähnlich dem hier angegebenen Datum / Uhrzeit-Beispiel.


2
Hast du das tatsächlich versucht? Ein direkter Aufruf führt zu: 'time.struct_time object' hat kein Attribut 'strftime'
Karl P

7
Entsprechend Ihrer Frage sprechen Sie über etwas anderes. Anfangs ging es in diesem Thread um das Formatieren eines datetimeObjekts aus dem Python-Modul datetime, aber Sie versuchen, ein struct_timeObjekt aus dem Low-Level- timeModul zu formatieren . struct_timeObjekte haben keine strftime()Methode, obwohl das Zeitpaket möglicherweise eine globale strftime()Methode enthält. Ich empfehle Ihnen jedoch, datetimestattdessen das High-Level- Paket (plattformunabhängig) zu verwenden.
Tux21b

2
Ich denke du meinstbabel.dates.format_datetime(value, format)
Johnboiles

2
Das Definieren eines neuen Filters ist in keiner Weise besser. Mehr Code zum Schreiben = mehr Code zum Verwalten = mehr Code zum Analysieren, Bit-Caching (falls verwendet) und Interpretieren. Einer der großen Vorteile der Verwendung von Jinja2 ist die Möglichkeit, kleinen Python-Code in die Vorlage zu schreiben. Einige der Leistungssteigerungen im Vergleich zum Vorlagensystem von Django sind darauf zurückzuführen.
StefanNch

4
@StefanNch "Einen neuen Filter zu definieren, ist in keiner Weise besser". Dies kann sein: Wenn der Filter in den Vorlagen mehrmals aufgerufen wird, wird die Wiederholung der Formatzeichenfolge vermieden und es kann weniger Code geschrieben werden. Und noch wichtiger, weniger wiederholter Code durch Hinzufügen einer Abstration.
Jacquev6

21

Hier ist der Filter, den ich für strftime in Jinja2 und Flask verwendet habe

@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) 

Und dann benutzt du den Filter so:

{{car.date_of_manufacture|strftime}}

2
Warum sind dateutilund native?
GWG


15

Wenn Sie mit einem Zeitobjekt niedrigerer Ebene arbeiten (ich verwende oft nur Ganzzahlen) und aus irgendeinem Grund keinen benutzerdefinierten Filter schreiben möchten, übergebe ich die strftime-Funktion als Variable an die Vorlage Es kann dort aufgerufen werden, wo Sie es brauchen.

Beispielsweise:

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

Welches kann dann verwendet werden in 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>

7

Sie können es so in der Vorlage ohne Filter verwenden

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


0

In einer Flasche mit Babel mache ich das gerne:

@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'))

in der Vorlage mit verwendet {{mydatetimeobject|dt}}

Also nein, mit Babel können Sie Ihre verschiedenen Formate in messages.po wie folgt angeben:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.