如何在 Flask/Jinja 模板中以不同于过滤器的方式使用管道?

Posted

技术标签:

【中文标题】如何在 Flask/Jinja 模板中以不同于过滤器的方式使用管道?【英文标题】:How to use pipe in Flask/Jinja template differently than filters? 【发布时间】:2016-04-19 22:42:04 【问题描述】:

我正在使用Flask 和Jinja2 templating engine 来构建网站。作为 ORM,我使用(优秀的)Peewee ORM,我现在遇到了问题。

在我的 Flask 视图中,我从数据库中获取了用户列表:

@app.route('/stats')
def stats():
    users = User.select()
    return render_template('stats.html', users=users)

在我的模板中,我遍历用户并尝试扩展查询。这有效:

% for user in users %
     user.app_logs.where(AppLog.type == 'LOGIN').first().created 
% endfor %

但是这个:

% for user in users %
     user.app_logs.where((AppLog.type == 'LOGIN') | (AppLog.type == AppLog.TICKET)).first().created 
% endfor %

给出TemplateSyntaxError: expected token 'name', got '('。我了解错误的来源:管道符号(|)定义为a filter in Jinja。所以我尝试用反斜杠 (\|) 转义它,但这不起作用。

所以我的问题是:有没有办法以某种方式逃避管道符号,或者是否有人有任何其他想法来完成这项工作?欢迎所有提示!

【问题讨论】:

我不知道 Peewee,但看起来它有一个 << 运算符,可以转换为 IN,所以 user.app_logs.where(AppLog.type << ['LOGIN', AppLog.TICKET]) 不能工作吗? @DanielRoseman - 旁边是一个更好的查询,这是个好主意。但不幸的是,这也不起作用:TemplateSyntaxError: unexpected '<'。感谢您使用 IN 进行此查询的提示! 在你的 User 模型上写一个方法并从你的模板中调用这个方法。 【参考方案1】:

无论如何,最好让模板保持“哑”并在模板之外进行查询。在您的情况下,您可以使用playhouse extension to use hybrid attributes on the model。

class User(Model):
    ...

    @hybrid_property
    def applog_login_ticket(self):
        return self.app_logs.where((AppLog.type == 'LOGIN') | (AppLog.type == AppLog.TICKET)).first().created()

然后在你的模板中你就可以做

% for user in users %
     user.applog_login_ticket 
% endfor %

【讨论】:

以上是关于如何在 Flask/Jinja 模板中以不同于过滤器的方式使用管道?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flask/Jinja2 将 HTML 传递给模板

flask jinja2模板引擎

Python Flask Jinja - 扩展模板时扩展/渲染模板

Flask jinja2模板注入思路总结

Flask jinja2 检索下拉列表的值

如何在 mac 中以不安全模式启动 chrome?