前言
用过 flask
的人肯定对 jinjia2
不会陌生,自然对 Jinjia2
自带的 filter
也有印象,但是其自带的 filter 实在有限,有些时候就不得不需要我们自己定义 filter
了,接下来的例子将介绍如何自定义 filter
自定义 filter
举个例子
自定义 filter 其实很简单,写一个函数实现你需要的功能,然后添加到 jinjia_env 中,这里以一个返回列表长度到自定义函数为例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from flask import Flask from flask import render_template
app = Flask(__name__)
def my_len(arg): return len(arg)
env = app.jinja_env env.filters['my_len'] = my_len
@app.route("/") def index(): test_str = "hello" return render_template("index.html", test_str=test_str)
if __name__ == "__main__": app.run()
|
ok 函数定义完了,接下来就是在模版中去使用了.
1 2 3 4 5 6 7 8 9 10 11
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>jinjia2模板测试</title> </head> <body> <h1>len: {{test_str|my_len}}</h1> </body> </html>
|
简单吧?到这里似乎就可以结束了?没问题,但是实际开发中大家很多人的目录结构都不是这样吧,在文件里有着为了优雅,有着一些
xxx.init_app(app)
的代码吧?所以接下来让我们试着把这些 filter
集成一下。
让 filter 优雅起来
尝试将这些 filter
封装到一个类中并且也实现 init_app
方法
1 2 3 4 5 6 7
| class Example: @staticmethod def init_app(app): @app.template_filter('my_len') def my_len(arg): return len(arg)
|
然后就可以在其他文件中像这样子使用了
1 2 3 4 5 6
| from examples import Example example = Example()
def create_app(app): example.init_app(app)
|
题外话 —— 自定义 function
有时候我们需要一个函数处理数据返回结果使得我们可以进行下一步操作,这个时候就需要用到 jinjia2
的自定义函数。
自定义 function
自定义函数的方法很简单,通过 add_template_global
即可
1 2 3 4 5 6 7 8 9 10 11 12
| def my_len(arg): return len(arg)
app.add_template_global(my_len,'my_len')
@app.template_global('my_len') def my_len(arg): return len(arg)
|
在模板中调用方法也与 filter
类似。
1 2 3 4 5 6 7 8 9 10 11
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>jinjia2模板测试</title> </head> <body> <h1>len: {{my_len(test_str)}}</h1> </body> </html>
|
用法很简单,那么问题来了,这两者有什么区别吗?
Jinjia2 的 function 和 filter 的区别
区别很简单,相较于 function
来说, filter
拥有访问上下文以及环境的能力,当然为了解决这个问题,jinjia2 有 contextfilter 等相关函数。
参考链接
Jinjia2
Difference between jinja2 functions and filters?