Jinja2'de bir tarihi nasıl biçimlendiririm?


183

Jinja2'yi kullanarak bir tarih alanını nasıl biçimlendiririm? Python'da bunu yapabileceğimi biliyorum:

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

Ama Jinja2'deki tarihi nasıl biçimlendiririm?

Yanıtlar:


327

Bunu yapmanın iki yolu var. Doğrudan yaklaşım, şablonunuzdaki strftime () yöntemini çağırmak (ve yazdırmak), örneğin

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

Görünürde daha iyi bir yaklaşım, kendi filtrenizi tanımlamak olacaktır, örneğin:

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)

(Bu filtre, i18n ile ilgili nedenlerden dolayı babile dayanmaktadır, ancak strftime'ı da kullanabilirsiniz). Filtrenin avantajı, yazabilmenizdir.

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

ki bu daha hoş görünüyor ve daha sürdürülebilir. Bir diğer yaygın filtre de "8 dakika önce yazılmış" gibi bir şeyi değerlendiren "timedelta" filtresidir. Bunun için kullanabilir babel.dates.format_timedeltave burada verilen datetime örneğine benzer bir filtre olarak kaydedebilirsiniz.


2
bunu gerçekten denedin mi doğrudan çağrıldığında: 'time.struct_time object' özelliğinin 'strftime' özelliği yoktur
Karl P

7
Sorunuza göre, farklı bir şeyden bahsediyorsunuz. İlk olarak, bu iş parçacığı datetimepython modülünden bir nesneyi biçimlendirmekle ilgiliydi datetime, ancak bir struct_timenesneyi düşük düzeyli timemodülden biçimlendirmeye çalışıyorsunuz . struct_timenesnelerin bir strftime()yöntemi yoktur, ancak strftime()zaman paketinde genel bir yöntem olabilir . Ancak datetimebunun yerine üst düzey (platformdan bağımsız) paketi kullanmanızı öneririz .
tux21b

2
Sanırım demek istiyorsunbabel.dates.format_datetime(value, format)
johnboiles

2
yeni bir filtre tanımlamak hiçbir şekilde daha iyi değildir. Yazılacak daha fazla kod = korunacak daha fazla kod = ayrıştırılacak daha fazla kod, bit önbelleğe alınır (kullanılıyorsa) ve yorumlanır. Jinja2'yi kullanmanın en büyük avantajlarından biri, şablonun içine küçük python kodu yazma yeteneğidir. Django'nun şablon sistemine kıyasla bazı performans kazançları bundan geliyor.
StefanNch

4
@StefanNch "yeni bir filtre tanımlamak hiçbir şekilde daha iyi değildir". Şunu olabilir: filtre şablonlarda birçok kez çağrılırsa, bu, biçim dizesinin tekrarlanmasını önler ve daha az kod yazılmasına neden olabilir. Ve daha da önemlisi, daha az tekrarlanan kod, bir soyutlama ekleyerek.
jacquev6

21

İşte Jinja2 ve Flask'ta strftime için kullandığım filtre

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

Ve sonra filtreyi şu şekilde kullanırsınız:

{{car.date_of_manufacture|strftime}}

2
Neden dateutilve native?
gwg


15

Daha düşük seviyeli bir zaman nesnesiyle uğraşıyorsanız (genellikle tamsayı kullanıyorum) ve herhangi bir nedenle özel bir filtre yazmak istemiyorsanız, kullandığım bir yaklaşım, strftime işlevini şablona bir değişken olarak aktarmaktır. ihtiyacınız olan yerde çağrılabilir.

Örneğin:

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

Hangi daha sonra içinde kullanılabilir 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

Herhangi bir filtre olmadan şablonda bu şekilde kullanabilirsiniz

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


0

şişede, babil ile bunu yapmayı seviyorum:

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

şablonda kullanılan {{mydatetimeobject|dt}}

bu yüzden hayır babel ile mesajlarda çeşitli formatınızı belirtebilirsiniz.po örneğin:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.