#Flask 30(第三篇v2) 请求钩子、模板语言
:路由(路由、配置等)
:视图(request、cookie&session、jsonify)
本篇:请求钩子、模板语言(变量+过滤器)
请求钩子
本质:在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要统一处理。目的:让每个视图函数避免编写重复功能的代码(可以理解成Django中的中间件)
四种常用请求钩子:
-
before_first_request
:处理app第一个请求前运行。 -
before_request
:在每次请求前运行。 -
after_request
:如果处理逻辑没有异常抛出,在每次视图函数处理完之后都被执行 -
teardown_request
:在每次视图函数处理完之后都被执行,无论是否有异常发生(工作在Debug=False)
from flask import Flask
app = Flask(__name__)
@app.route('/')
def helloworld():
return 'hello world'
# 在第一次请求之前运行,比如连接数据库操作只需要执行一次
@app.before_first_request
def before_first_request():
print('before_first_request')
# 在每一次请求都会执行,可以在这里做权限校验操作,比如说某用户是黑名单用户,黑名单用户登录系统将遭到拒绝访问
@app.before_request
def before_request():
print('before_request')
# 在请求之后运行
@app.after_request
def after_request(response):
# response: 就是前面的请求处理完毕之后, 返回的响应数据
print('after_request')
return response
# 每一次请求之后都会调用,会接受一个参数,参数是服务器出现的错误信息
@app.teardown_request
def teardown_request(error):
print('teardown_request: error %s' % error)
if path in [url_for(index),url_for(order)]:
.... # 某一些路径下的视图函数集中做处理
if __name__ == '__main__':
app.run(debug=False)
模板语言
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/index')
def index():
return render_template('index.html',name='egg',age=39)
# 第一个参数是模板的页面,后面的参数是把要传的变量平铺开
1、变量
data = {
'name':'egg', #{{name}}
'my_dict':{'city':'fz'}, #{{my_dict.city}}
'my_list':[1,2,3,4], #{{my_list}};{{my_list.1}};
}
#django中{{}}这里面的变量不支持直接相加,但flask支持:{{my_list.1+my_list.2}},也支持字符串相加(即拼接)
2、过滤器
{{变量 |trim|upper}} 支持链式使用过滤器
safe:禁用转义
capitalize:首字母大写,其余小写
lower:全转小写
upper:全转大写
title:每个单词首字母转大写
trim:首尾空格去掉
reverse:字符串反转(hello变成olleh)
format:格式化输出{{'%s is %d' | format('name',39)}}
3、列表过滤器
first:取第一个元素{{[1,3,4,5] | first}}
last:取最后一个元素
length:获取列表长度{{[1,3,4,5] | length}}
sum:列表求和{{[1,3,4,5] | sum}}
sort:列表排序{{[1,3,4,5] | sort}}
4、自定义过滤器
a.本质上是写一个函数。
-
函数有一个传入的参数,就是这个要处理的变量{{变量...}} -
函数return的结果是{{}}最后输出的结果
b.写完函数后flask并不知道他的存在,要注册过滤器(告诉flask我的存在)
#第一种注册过滤器的方式:
def list_step_2(li): # 这是一个对列表隔一个值取值的自定义过滤器
return li[::2]
app.add_template_filter(list_step_2,"li2") # 注册过滤器,两个参数:函数名,过滤器名称
-------------------------------
#第二种注册过滤器的方式:(注意看,不是@app.add_template_filter('li2'))
@app.template_filter('li2')
def list_step_2(li):
return li[::2]
---------------------------------
模板中这么使用{{my_list | li2}}
5、模版语言中的执行语句是{%...%} ,很好记:两个%像两个车轮一样在run,所以是可执行的语句。而变量,或者是函数调用(结果也是返回一个值的),都是用{{...}}
6、模版渲染的时候有一些变量和方法是可以直接{{...}}这样使用的,有:config对象、request对象,url_for()方法,get_flashed_messages()方法
7、模板闪现:get_flashed_messages()方法细说一下,在后端from flask import Flask,flash
有个flash()函数,可以把"需要给前端展示的信息"塞到flash中,比如flash('用户名不能为空')
,然后在模板中可以直接通过{{get_flashed_messages()}}来提取flash中的信息。这个信息只能在此次请求中提取,下次请求来的时候flash就是清空状态的,相当于一个数据的临时存放点。(底层需要用到session,SECRET_KEY需要设置值)
模板宏
模板宏类似于函数的概念,可以在模板中重复利用代码,避免冗余.
# 定义:
{% macro input() %}
<input type="text" value="">
{%...此处可以有可执行语句...%}
{% endmacro %}
# 使用:
{{input()}}
变形1:可以传参
{% macro input(type,value,szie) %}
<input type="{{type}}" value="{{value}}">
{% endmacro %}
{{input('password','aaa')}}
---------------------------------
变形2:可以提供默认值
{% macro input(type="text",value="111") %}
<input type="{{type}}" value="{{value}}" >
{% endmacro %}
{{input('password','aaa')}}
{{input()}}
--------------------------------------
变形3:可以把宏定义在外部,即:专门用一个html文件(macro_input.html)只写宏的内容(与前面变形2内容一致)
{% import "macro_input.html" as m_input %}
{{ m_input.input()}}
此外,模板的知识点还有:模板继承、模板包含(include);这里写的比较粗糙,具体使用具体查