Jinja2 - 过滤器优化(Datetimeformatter)

Jinja 2 - Filter Optimization (Datetime Formatter)

我在 Flask Web 应用程序中使用 Jinja 2 过滤器。 Jinja 过滤器执行以下操作:

  1. 根据用户的时区转换日期时间。
  2. 根据用户的时区格式化日期。

这里的东西是用户的时区保存在数据库中。 由于每个用户在我的应用程序中加载某些页面时都会调用此过滤器数十次,因此数据库也被查询了数十次。

如何减少此过滤器中对数据库的查询次数? 我可以只查询一次用户的时区并以某种方式将其保存为 Flask 中的全局变量吗?

代码:

# set jinja2 filter - convert utc to user's tz and format the time
def datetimefilter(value):
    try:
        # query user's time zone
        try:
            tz = pytz.timezone(db.session.query(Users.user_tz).filter(Users.id == session['_user_id']).first()[0])
        # else set utc
        except Exception as e:
            tz = pytz.timezone('UTC')

        # query user's country
        try:
            country = pytz.timezone(db.session.query(Users.country).filter(Users.id == session['_user_id']).first()[0])
        except Exception as e:
            country = None

        # set format according to country
        if str(country) in ['United States', 'US', 'USA']:
            format = "%m/%d/%Y, %H:%M"
        else:
            format = "%d/%m/%Y, %H:%M"

        # convert time zone and format time
        utc = pytz.timezone('UTC')
        tz_aware_dt = utc.localize(value)
        local_dt = tz_aware_dt.astimezone(tz)
        return local_dt.strftime(format)

    except Exception as e:
        return value

# create filter
app.jinja_env.filters['datetimefilter'] = datetimefilter

您可以在路由处理函数中一次获取国家和时区,并将它们作为变量传递给模板。

Jinja2 custom filters 除了要过滤的值外,还可以接受多个参数,因此将这些变量传递给过滤器。

这是一个简单的例子

import datetime as dt

from jinja2 import Environment
import pytz


def datetimefilter(value, tz, country):
    try:

        # set format according to country
        if str(country) in ['United States', 'US', 'USA']:
            format = "%m/%d/%Y, %H:%M"
        else:
            format = "%d/%m/%Y, %H:%M"

        # convert time zone and format time
        utc = pytz.timezone('UTC')
        tz_aware_dt = utc.localize(value)
        local_dt = tz_aware_dt.astimezone(tz)
        return local_dt.strftime(format)

    except Exception:
        return value


# Create and register the filter and template
env = Environment()
env.filters['datetimefilter'] = datetimefilter
template = env.from_string("It's {{ now | datetimefilter(tz, country) }}!")

user_tz = pytz.timezone('US/Eastern')
user_country = 'US'
rendered = template.render(now=dt.datetime.now(), tz=user_tz, country=user_country)
print(rendered)

结果:

It's 12/19/2020, 05:35!