Làm cách nào để định dạng một ngày trong Jinja2?


183

Sử dụng Jinja2, làm cách nào để định dạng trường ngày? Tôi biết trong Python tôi chỉ đơn giản có thể làm điều này:

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

Nhưng làm cách nào để định dạng ngày trong Jinja2?

Câu trả lời:


327

Có hai cách để làm điều đó. Cách tiếp cận trực tiếp sẽ chỉ đơn giản là gọi (và in) phương thức strftime () trong mẫu của bạn, ví dụ

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

Một cách tiếp cận khác tốt hơn sẽ là xác định bộ lọc của riêng bạn, ví dụ:

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)

(Bộ lọc này dựa trên babel vì những lý do liên quan đến i18n, nhưng bạn cũng có thể sử dụng strftime). Ưu điểm của bộ lọc là bạn có thể viết

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

trông đẹp hơn và dễ bảo trì hơn Một bộ lọc phổ biến khác cũng là bộ lọc "timedelta", đánh giá một cái gì đó như "được viết 8 phút trước". Bạn có thể sử dụng babel.dates.format_timedeltacho điều đó và đăng ký nó dưới dạng bộ lọc tương tự như ví dụ datetime được đưa ra ở đây.


2
bạn đã thực sự thử điều đó? gọi nó trực tiếp dẫn đến: 'time.struct_time object' không có thuộc tính 'strftime'
Karl P

7
Theo câu hỏi của bạn, bạn đang nói về một cái gì đó khác nhau. Ban đầu, chủ đề này là về định dạng một datetimeđối tượng từ mô-đun python datetime, nhưng bạn đang cố gắng định dạng một struct_timeđối tượng từ timemô-đun cấp thấp . struct_timecác đối tượng không có một strftime()phương thức, mặc dù có thể có một strftime()phương thức toàn cầu trong gói thời gian. Nhưng tôi khuyên bạn nên sử dụng gói cấp cao (độc lập với nền tảng) datetime.
tux21b

2
Tôi nghĩ bạn có nghĩa làbabel.dates.format_datetime(value, format)
johnboiles

2
xác định một bộ lọc mới, không phải là tốt hơn trong bất kỳ cách nào. Nhiều mã hơn để viết = nhiều mã hơn được duy trì = nhiều mã được phân tích cú pháp, lưu trữ bit (nếu được sử dụng) và diễn giải. Một trong những lợi thế lớn của việc sử dụng Jinja2 là khả năng viết mã python nhỏ bên trong mẫu. Một số tăng hiệu suất, so với hệ thống mẫu của Django, xuất phát từ đó.
StefanNch

4
@StefanNch "xác định bộ lọc mới, không tốt hơn bằng mọi cách". Nó có thể là: nếu bộ lọc được gọi nhiều lần trong các mẫu, điều này tránh lặp lại chuỗi định dạng và có thể dẫn đến việc viết ít mã hơn. Và thậm chí quan trọng hơn, mã ít lặp lại , bằng cách thêm một bản tóm tắt.
jacquev6

21

Đây là bộ lọc mà tôi đã sử dụng cho strftime trong Jinja2 và 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) 

Và sau đó bạn sử dụng bộ lọc như vậy:

{{car.date_of_manufacture|strftime}}

2
Tại sao dateutilnative?
gwg


15

Nếu bạn đang xử lý một đối tượng thời gian ở mức thấp hơn (tôi thường chỉ sử dụng số nguyên) và không muốn viết bộ lọc tùy chỉnh vì bất kỳ lý do gì, một cách tiếp cận tôi sử dụng là chuyển hàm strftime vào mẫu dưới dạng một biến, trong đó nó có thể được gọi là nơi bạn cần nó.

Ví dụ:

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

Mà sau đó có thể được sử dụng trong 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

Bạn có thể sử dụng nó như thế này trong mẫu mà không cần bất kỳ bộ lọc

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

4

Người dùng Google App Engine: Nếu bạn đang chuyển từ Django sang Jinja2 và đang tìm cách thay thế bộ lọc ngày, hãy lưu ý rằng mã định dạng% là khác nhau.

Mã% strftime ở đây: http://docs.python.org/2/l Library / datetime.html # strftime-and-strptime-behavior


0

Trong bình, với babel, tôi thích làm điều này:

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

được sử dụng trong mẫu với {{mydatetimeobject|dt}}

vì vậy, không có babel, bạn có thể chỉ định định dạng khác nhau của mình trong tin nhắn. Ví dụ như thế này:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.