Jinja2基础使用
层级关系
flask_test
|__templates
| |__index.html
|__app.py
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{user.user}}</title> </head> <body> <a href="{{url_for('escape_index')}}">return</a> <h2>{{user.user}}</h2> {% if user.burs %} <i>{{user.burs}}</i> {% else %} <i>233333</i> {% endif %} <ul> {% for mouv in mours %} <li>{{mouv.name}}--{{mouv.year}}</li> {% endfor %} </ul> </body> </html>
app.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask, request, render_template,render_template_string from jinja2 import escape """ html字符实体转义:https://dev.w3.org/html5/html-author/charref jinja2使用 语法 语句 if判断 for循环 ==》 {% --- %} 表达式 字符串、变量、函数调用 ==》 {{ --- }} PS 获取变量属性 ==》. [例:user.username] 允许使用 对象:字符串、列表、字典、元组、整型、浮点型、布尔值 运算符:+、 -、 *、 / 比较符号:==、 != 逻辑符号:and or not in is None 布尔值 示例: user={'user':'gg','burs':'you love'} mours = [{'name':1,'year':"ss"},{'name':2,'year':"uu"}] if判断: {% if user.burs %} <i>{{user.burs}}</i> {% else %} <i>233333</i> {% endif %} # 需要有endif做结尾 for循环:[http://jinja.pocoo.org/docs/2.10/templates/#for]==>for循环相关 <ul> {% for mouv in mours %} <li>{{mouv.name}}--{{mouv.year}}</li> {% endfor %} # 需要有endfor做结尾 </ul> ps:for循环特殊变量 loop.index 当前迭代数【从1开始计数】 loop.index0 当前迭代数【从0开始计数】 loop.revindex 当前反向迭代数【从1开始计数】 loop.revindex0 当前反向迭代数【从0开始计数】 loop.first 如果是第一个元素则为True loop.last 如果是最后一个元素则为True loop.previtem 上一个迭代的条目 loop.nextitem 下一个迭代的条目 loop.length 序列包含的元素数目 escape:用于安全转义 """ app = Flask(__name__) @app.route('/escape') def escape_index(): """escape:用于安全转义""" name = request.args.get('name') return '<h1>hello {}</h1>'.format(escape(name)) @app.route('/templates') def templates(): """ render_template() 渲染函数 render_template_string() 用来渲染模板字符串 PS:传入的jinja2的变量值可以是字符串、列表、和字典,也可以是函数、类和类实例 实例: <p>这是列表mylist第一个元素{{ mylist[0] }}</p> <p>这是元组mytuple第一个元素{{ mytuple[0] }}</p> <p>这是字典mydict第一个元素{{ mydict["name"] }}</p> <p>这是函数myfunc的返回值{{ myfunc() }}</p> <p>这是对象myobject的调用某个方法返回值{{ myobject.name() }}</p> :return: """ user = {'user': 'gg', 'burs': 'you love'} mours = [{'name': 1, 'year': "ss"}, {'name': 2,'year': "uu"}] return render_template('templations.html', user=user, mours=mours) if __name__ == '__main__': app.run()
Jinja2上下文
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask, request, render_template,render_template_string,url_for,get_flashed_messages from jinja2 import escape """ 上下文 1、变量 模板上下文包含了很多变量,其中包括我们调用render_template()函数时手动传入的变量以及Flask默认传入的变量。 除了渲染时传入变量,你也可以在模板中定义变量,使用set标签: {% set navigation = [('/', 'Home'),('/about', 'About')] %} 也可以将一部分模板定义成变量,使用set和enfset标签声明 {% set navigation %} <a href="/">Home</a> <a href="/about">About</a> {% endset %} 2、标准模板全局变量 config 当前的配置对象 request 当前的请求对象,在已经激活的请求环境中可用 session 当前的回话对象,在已经激活的请求环境中可用 g 与请求绑定的全局变量,在已经激活的请求环境中可用 3、自定义上下文 app.context_processor装饰器 4、全局对象 在所有模板中都可以使用的对象 1、内置全局函数 A:jianja2模板中内置全局函数【常见】==》jianja2模板中内全量全局函数列表链接 http://jinja.pocoo.org/docs/2.10/templates/#list-of-global-functions range([start,]stop[,stop]) 和python中的range()用法相同 lipsum(n=5, html=True, min=20, max=100) 生成随机文本默认为5段html文本,每段包含20到100字符 dict(**items) 和python中的dict()用法相同 B:Flask内置模板全局函数 url_for() 用于生成url的函数 例:<a href="{{url_for('escape_index')}}">return</a> get_flashed_messages() 用于获取flask消息的函数 2、自定义全局函数 """ app = Flask(__name__) @app.context_processor def inject_foo_one(): """ 原理: 如果多个模板都需要使用同一变量,那么比起在多个视图函数中重复传入,更好的方法是能够设置一个模板全局变量。 Flask提供了一个app.context_processor装饰器,可以用来注册模板上下文处理函数,它可以帮我们完成统一传入变量的工作。 模板上下文处理函数需要返回一个包含变量键值对的字典 html中调用方法:<h2>{{foo}}</h2> 使用方式 第一种:函数inject_foo_one 第二种:函数inject_foo_two 第三种:使用lambda简化成 @app.context_processor(lambda: dict(foos='inject_foo_three')) :return: """ foo = 'I am inject_foo' return dict(foo=foo) def inject_foo_two(): """方法二""" foot = 'inject_foo_two' return dict(foot=foot) @app.context_processor(inject_foo_two) @app.route('/escape') def escape_index(): """escape:用于安全转义""" name = request.args.get('name') return '<h1>hello {}</h1>'.format(escape(name)) @app.route('/templates') def templates(): """ """ user = {'user': 'gg', 'burs': 'you love'} mours = [{'name': 1, 'year': "ss"}, {'name': 2,'year': "uu"}] return render_template('templations.html', user=user, mours=mours) @app.template_global() def bar(): """ 除了使用app.context_processor注册模板上下文处理函数来传入函数,也可以使用app.template_global装饰器直接将函数注册为模板全局函数 PS:默认使用函数的原名称传入模板,在@app.template_global()装饰器使用name参数可以指定一个自定义名称 @app.add_template_global("name") ==> 注册自定义全局函数,传入函数对象可选的自定义名称 :return: """ return 'I bar' if __name__ == '__main__': app.run()
过滤器
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask,render_template from flask import Markup from jinja2 import escape """ 过滤器 在Jinja2中,过滤器(filter)是一些可以用来修改和过滤变量值的特殊函数,过滤器和变量用一个竖线(管道符号)隔开, 需要参数的过滤器可以像函数一样使用括号传递。 例: {{ name|title }} ==> python中的name.title {{ movies|length }} ==> python中的len(movies) 另一种使用方法 将过滤器作用于一部分模板数据,使用filter标签和endfilter标签声明开始和结束 {% filter upper %} over upper {% endfilter %} 常用内置过滤器 default(value, default_value=u", boolean=False) 设置默认值,默认值作为参数传入,别名为d escape(s) 转义html文本,别名为e first(seq) 返回序列的第一个元素 last(seq) 返回序列的最后一个元素 length(object) 返回变量的长度 random(seq) 返回序列中的随机元素 safe(value) 将变量值标记为安全,避免转义 trim(value) 清除变量值前后的空格 max(value, case_sensitive=False,attribute=None) 返回序列中的最大值 min(value, case_sensitive=False,attribute=None) 返回序列中的最小值 unique(value, case_sensitive=False,attribute=None) 返回序列中的不重复值 striptags(value) 清除变量值内的html标签 urlize(value, trim_url_limit=None, nofollow=False, target=None, rel=None) 将url文本转换为可单击的html链接 wordcount(s) 计算单词数量 tojson(value, indent=None) 将变量值转化为json格式 truncate(s, length=255, killwords=False, end='...', leeway=None) 截断字符串,常用于显示文章摘要,length参数设置截断的长度, killwords参数设置是否截断单词,end参数设置结尾的符号 全量内置过滤器链接 http://jinja.pocoo.org/docs/2.10/templates/#builtin-filters 过滤器叠加使用用例 <title>{{name|default('默认人')|title}}</title> ==> 将name变量设置默认值,并同时标题化 传输文本消毒方式 """ app = Flask(__name__) @app.route('/index') def index(): """ 文本传输消毒方式 方式一 escape()函数对变量进行转义 方式二 from flask import Markup ps:在文本中可以直接使用{{text}} :return: """ text = Markup("<h1>HELLO FLASK</h1>") return render_template('index.html', text=text) @app.template_filter() def Disinfect(s): """ 自定义过滤器 和注册全局函数类似,可以在app.template_filter()中使用name关键字设置过滤器的名称,默认会使用函数名称。 过滤器函数需要接收被处理的值作为输入,返回处理后的值。过滤器函数接收s作为被过滤的变量值,返回处理后的值。 创建的 Disinfect过滤器会在被过滤的变量字符后面添加一个音符图标,因为音符通过HTML实体♫表示, 使用 Markup类将它标记为安全字符。在使用时和其他过滤器用法相同 {{ name|Disinfect }} ps:可以直接使用app.add_template_filter() 方法注册自定义过滤器,传入函数对象和可选的自定义名称(name) 例:app.add_template_filter(your_filter_function) :param s: :return: """ return s + Markup(' ♫') if __name__ == '__main__': app.run()
测试器
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask """ 测试器 内置测试器 全量内置测试器:http://jinja.pocoo.org/docs/2.10/templates/#list-of-builtin-tests 使用: 在使用测试器时,is的左侧是测试器函数的第一个参数(value),其他参数可以添加括号传入,也可以在右侧使用空格连接 {% if foo is sameas(bar) %} == {% if foo is sameas bar %} 自定义测试器 """ app = Flask(__name__) @app.template_test() def baz(z): """ 自定义测试器 使用template_test装饰器来注册一个自定义测试器 PS:也可以使用add_template_test() 方法来注册自定义测试器,传入函数对象和可选的自定义名称 例 @app.add_template_test(baz,name='baz') :param s: :return: """ if z == 'baz': return True return False if __name__ == '__main__': app.run()
Environment类
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask import jinja2 """在Jinja2中,渲染行为由jinja2.Environment类控制,所有的配置选项、上下文变量、全局函数、过滤器和测试器都存储在Environment实例上""" jinja2.Environment() """ 例:各种字符定义 block_start_string=BLOCK_START_STRING, block_end_string=BLOCK_END_STRING, variable_start_string=VARIABLE_START_STRING, variable_end_string=VARIABLE_END_STRING, comment_start_string=COMMENT_START_STRING, comment_end_string=COMMENT_END_STRING BLOCK_START_STRING = '{%' BLOCK_END_STRING = '%}' VARIABLE_START_STRING = '{{' VARIABLE_END_STRING = '}}' COMMENT_START_STRING = '{#' COMMENT_END_STRING = '#}' """ # 当jinja2与Flask结合后,便不再单独创建Environment对象了,而是使用Flask创建的Environment对象,存储在app.jinja_env属性上 app = Flask(__name__) # 修改标记注释结尾的字符串 app.jinja_env.comment_end_string = '[[' """ 模板环境中的全局函数、过滤器和测试器分别存储在 Environment对象的 globals、 filters和 tests属性中,这三个属性都是字典对象。 除了使用Flask提供的装饰器和方法注册自定义函数,也可以直接操作这三个字典来添加相应的函数或变量,这通过向对应的字典属性中添加一个 键值对实现,传入模板的名称作为键,对应的函数对象或变量作为值。 """ # 示例:添加自定义全局对象,此与app.template_global()装饰器不同,直接操作global字典允许传入任意python对象 text1 = "one to one" def fun(): return "func" app.jinja_env.globals["text1"] = text1 app.jinja_env.globals["fun"] = fun # 添加自定义过滤器 def func(s): return s + "@+@" app.jinja_env.filters["func"] = func # 添加自定义测试器 def funct(n): if n == "a": return True return False app.jinja_env.tests["funct"] = funct # 全量 Environment对象方法 http://jinja.pocoo.org/docs/latest/api/#jinja2.Environment