flask 模板
- 视图函数主要作用是生成请求的响应,包含两个作用:处理业务逻辑和返回响应内容。
- 模板作用:承担在大型项目内的返回响应内容的作用。
- 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
使用真实值替换变量,再返回最终得到的字符串,这个过程称为“渲染”
Flask是使用 Jinja2 这个模板引擎来渲染模板
1 jinja2简介
1 Flask内置的模板语言;2 模板语言是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名。
使用:
变量代码块:{{}}
<h1>{{ post.title }}</h1>
控制代码块:{% %}
实现语言层次的一些功能,语句控制输出。
if语句:
{% if 判别条件 %}
语句1
{% elif 判别条件 %}
语句2
{% endif %}
for 语句:
{% for data in data_list %}
循环语句
{% endfor %}
注释语句:
{{# #}}
render_template
Flask提供render_template函数封装模板引擎。
render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量。
@app.route('/')
def index():
data = "itpycharm"
return render_template('temp_demo1.html',data=data)
2 模板的使用
项目下创建 templates 文件夹,其内放置所有模板文件。
pycharm可以设置templates 文件夹属性(mark)以便能够在代码中有智能提示。
设置 html 中的模板语言Templates,以便在 html 有智能提示
3 过滤器
过滤器的本质就是函数。
过滤器:对字符串的处理,格式化输出数据。默认开启转义,会把变量的标签使用字符串形式显示。基于模板函数render_template。
语法格式:{{变量 | 过滤器}}
支持链式调用。
<p>反转首字母大写:{{ 'ANiHc FO KnAb' | reverse | capitalize }}</p>
字符串操作:
safe:禁用转义,开始解析标签字符串。
{{ '<em>hello world</em>' | safe }}</p>
reverse:翻转,原字符串进行反序输出
upper:大写,原字符串全部大写。
lower:小写,原字符串全部小写
title:把值中的每个单词的首字母都转成大写
capitalize:首字符大写。
format:格式化输出;
列表操作:
last first sum length sort(排序)
format:格式化输出
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>' | striptags }}</p>
语句块过滤:
{% filter upper %}
#一大堆文字#
{% endfilter %}
3.1 自定义过滤器
自定义过滤器有两种实现方式:
注意:自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。
方式一,add_template_filter 方法
通过调用Flask应用对象的 add_template_filter 方法实现自定义过滤器。
def do_listreverse(li):
# 通过原列表创建一个新列表
temp_li = list(li)
# 将新列表进行返转
temp_li.reverse()
return temp_li
app.add_template_filter(do_listreverse,'lireverse')
该方法第一个参数是函数名,第二个参数是自定义的过滤器名称:
方式二,通过装饰器来实现自定义过滤器
装饰器传入的参数是自定义的过滤器名称。
@app.template_filter('lireverse')
def do_listreverse(li):
# 通过原列表创建一个新列表
temp_li = list(li)
# 将新列表进行返转
temp_li.reverse()
return temp_li
在 html 中使用自定义过滤器
<br/> my_array 原内容:{{ my_array }}
<br/> my_array 反转:{{ my_array | lireverse }}
1.1 控制代码块
if 代码块、for代码块
在一个 for 循环块中你可以使用loop特殊的变量访问一些信息:
变量 描述
loop.index 当前循环迭代的次数(从 1 开始)
loop.index0 当前循环迭代的次数(从 0 开始)
loop.revindex 到循环结束需要迭代的次数(从 1 开始)
loop.revindex0 到循环结束需要迭代的次数(从 0 开始)
loop.first 如果是第一次迭代,为 True 。
loop.last 如果是最后一次迭代,为 True 。
loop.length 序列中的项目数。
loop.cycle 在一串序列间期取值的辅助函数。
4 模板代码复用
使用 JinJa2 模板中的 宏、继承、包含方法实现减少多个模板中代码的重复。
模板宏
对宏(macro)的理解:
- 类似Jinja2 中的一个函数,它会返回一段HTML模板代码。
- 宏可以写在一个单独文件内,再让多个模板进行调用。
使用 - 定义宏
{% macro input(name,value='',type='text') %}
<input type="{{type}}" name="{{name}}"
value="{{value}}" class="form-control">
{% endmacro %}
- 调用宏
{{ input('name' value='hello Python')}}
- 输出
<input type="text" name="name"
value="hello Python" class="form-control">
抽取宏HTML文件
- 把宏单独抽取出来,封装成html文件,文件名可以自定义macro.html
{% macro function(type='text', name='', value='') %}
<input type="{{type}}" name="{{name}}"
value="{{value}}" >
{% endmacro %}
- 在其它模板文件中先导入,再调用
{% import 'macro.html' as macr %}
{% macr.function() %}
模板继承
模板继承可以多次使用重复的内容。
一般继承主要使用在网站的顶部菜单、底部。
父模板定义block 内容,子模板直接继承使用。
定义格式:
{% block top %}
标签定义的内容
{% endblock %}
- 子模板使用 extends 指令声明这个模板继承自哪个模板
- 父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()
父模板base.html
{% block top %}
顶部菜单
{% endblock top %}
{% block content %}
{% endblock content %}
{% block bottom %}
底部
{% endblock bottom %}
子模板
extends指令声明这个模板继承自哪
{% extends 'base.html' %}
{% block content %}
子模板需要填充的内容
{% endblock content %}
- 模板继承使用时注意点:
- 不支持多继承
- 子模板第一行书写extends,便于阅读。
- 同一模板文件,block名字不能重复
- 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。
模板包含
Jinja2模板中,包含(Include)方法。
将另一个模板整个加载到当前模板中,并直接渲染。
Include的使用:
{% include 'hello.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常。加上 ignore missing 关键字,如果包含的模板文件不存在,会忽略这条include语句。
Include 加上关键字ignore missing:
{% include 'hello.html' ignore missing %}
小结
宏(Macro)、继承(Block)、包含(include)均能实现代码的复用。
继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。
宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。
包含(include)是直接将目标模板文件整个渲染出来。
模板特有变量和函数
Flask 默认内置模板的函数和对象。
config
你可以从模板中直接访问Flask当前的config对象;
配置数据库:
{{config.SQLALCHEMY_DATABASE_URI}}
mysql://root:mysql/database
request
就是flask中代表当前请求的request对象:
{{request.url}}
http://127.0.0.1
session
为Flask的session对象
{{session.new}}
True
g变量
在视图函数中设置g变量的 name 属性的值,然后在模板中直接可以取出
{{ g.name }}
url_for()
url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接:
{{url_for('home')}}
/
如果我们定义的路由URL是带有参数的,则可以把它们作为关键字参数传入url_for(),Flask会把他们填充进最终生成的URL中:
{{ url_for('post', post_id=1)}}
/post/1
get_flashed_messages()
这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉:
{%for message in get_flashed_messages()%}
{{message}}
{%endfor%}