之前我们只简单了解了模板,今天我们具体来说说模板中的几个基本使用:
过滤器&自定义过滤器
控制代码块
sa'nsan宏、继承、包含
Flask 的模板中特有变量和方法
web表单
CSRF
今天主要来说说Flask中的过滤 继承 包含 和宏
过滤器
过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器。
这里我们这几个方法我们还是用 上次的py文件,稍微改动一个,具体代码如下,注释,注意事项都包含在里面:
# -*- encoding: utf-8 -*- #网页模板需要导入render_template from flask import Flask,render_template #建立对象 app=Flask(__name__) app.config.from_pyfile('config.ini') #自定义一个过滤器 def my_filter(val): return '$' + str(val) #将自定义的过滤器函数,赋给模板,第一个参数是自定义的过滤器名称,第二个参数是模板中调用的标识 app.add_template_filter(my_filter,'my_filter') @app.route('/') def index(): my_str = '你好世界' my_int=123 my_list=['万','丈','高','楼','平','地','起'] my_dict={'name':'xiaowang'} context={} context['my_str']=my_str context['my_int']=my_int context['my_list']=my_list context['my_dict']=my_dict #使用render_tempate模板来渲染文件,通过第二个参数传递数据变量 # return render_template('day3.html',my_str=my_str,my_int=my_int,my_list=my_list,my_dict=my_dict) #通过**引用来嵌套dict直接传递给模板 return render_template('body.html',**context)
这里return中返回的文件名在后边不一一写出来了,我们只需建一个模板文件,每次把文件名字传进去让它进行跳转 if __name__ == "__main__": app.run()
注意上边代码中最后一个return中返回的文件名在后边不一一写出来了,我们只需建一个模板文件,每次把文件名字传进去让它进行跳转
过滤器文件代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>flask过滤器的学习</title> </head> <body> {# 过滤器调用方式{{变量 | 过滤器名称}}#} safe过滤器,可以禁用转义 {{'<strong>hello</strong>'| safe}} <br> 把大写字母转会为小写 {{'HELLO' | lower}} <br> 把小写字母转换为大写 {{'hello' | upper}} <br> 字符串反转 {{'abc' | reverse}} <br> 首字母大写 其余字母小写 {{'james' | capitalize}} <br> 过滤html标签 em标签是斜体,这里striptage 和转义没有关系 {{'<em>hello</em>' | striptags}} <br> 只显示list首个元素 {{[100,99,86] | first}} 只显示list最后一个元素 {{[100,99,86] | last}} 显示一个list的长度 {{[1,2] | length}} 对list里的所有元素求和 {{[1,2,3] | sum}} 对list进行排序 {{[2,5,3,6,4,9] | sort}} 对语句快进行过滤 {% filter upper%} jfsdhjhuwewdshgjsdgh {% endfilter %} 链式调用过滤器 {{'abc' | reverse | upper }} </body> </html>
宏
把它看作 Jinja2 中的一个函数,它会返回一个模板或者 HTML 字符串
为了避免反复地编写同样的模板代码,出现代码冗余,可以把他们写成函数以进行重用
需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>flask 宏编程</title> </head> <body> 定义一个宏 {% macro input(value,type,id)%} <input id='{{id}}' type="{{type}}" value="{{value}}"/> {% endmacro%} <br> 调用宏 {{input(type='button',value='男人',id='abc')}} </body> </html>
继承
模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。
说起继承肯定要有一个父模板一个子模板:
这里代码我就简单演示一下:
父模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>主模板</title> </head> <body> {# 模板继承使用block关键字 #} {% block top %} 这里是导航栏 {% endblock top %} {% block content%} 需要被继承内容,在这里填充 {% endblock content %} </body> </html>
子模板:
{# 继承模板使用extebds关键字 #}
{% extends 'day3_base.html' %}
{% block content %}
我来继承
{% endblock content %}
包含
Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。它的功能是将另一个模板整个加载到当前模板中,并直接渲染。
include的使用 如:
{% include 'hello.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上 ignore missing 关键字。如果包含的模板文件不存在,会忽略这条include语句
包含也为两个模板文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>模板包含的学习</title> </head> <body> {# 使用 include 关键字,来包含之前定义好的模板#} {% include 'day3_top.html'%} </body> <div> 这里是身体 </div> </html>
被包含的模板,简单演示一下:
<!-- 头部文件,自定义局部的内容 --> <div> 这里是头部,可以被包含的 </div>
总结:
宏(Macro)、继承(Block)、包含(include)均能实现代码的复用。
继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。
宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。
包含(include)是直接将目标模板文件整个渲染出来。