目录
reqeust:请求钩子
@app.before_first_request
@app.before_requset:一个app可以定义多个before_request,从上往下执行。
@app.after_request
@app.teardown_request
from flask import Flask
app = Flask(__name__)
@app.before_first_request
def first_action():
# 服务第一次要做的事情,第一次完成后,后续不再执行
# 例如设置某些全局变量
print('设置全局变量')
# 数据埋点
@app.before_request
def get_visit_num():
# 1。一个请求发起之前的操作,比如链接数据库,查询某个接口的访问数量
# 2。访问该接口
# 3。接口数量+1
# 4。不可使用return,使用了就会中断,一般用来设置
print('访问数量+1')
@app.after_request
def make_res(response):
# 请求之后的操作,比如修改响应中的headers信息,当respose错误时,就不会触发
response.headers['server'] = 'chuntian'
@app.teardown_request
def tear_down_action():
# 无论response是否错误,都会执行,比如中断数据库链接
print('中断数据库链接')
g: g变量,不可跨请求
g变量的作用:在同一个请求中共享数据,可以将g变量理解为一个对象,对对象的操作或访问通过g.xxx。
共享用户信息
from flask import Flask, request, g
app = Flask(__name__)
@app.before_request
def get_visit_num():
token = request.args.get('token')
g.user = token + 'md5' # 此时g.user可以在@app.after_request中获取到
@app.after_request
def make_res():
print(g.user)
共享数据库连接:对数据库的操作
import pymysql as pymysql
from flask import Flask, g
app = Flask(__name__)
def db_connect():
conn = pymysql.connect(
host='localhost',
user='root',
password='123456',
db='tasks',
port=3306,
charset='utf8mb4'
)
return conn.cursor()
@app.before_request
def get_db():
if 'db' not in g:
# 把游标cursor存到g变量的db属性中
g.db = db_connect()
@app.teardown_request
def close_db():
db = g.pop('db', None)
if db is not None:
db.close()
@app.route('/register',methods=['GET','POST'])
def register():
sql = 'select * from tasks where id =xxx;'
g.db.excute(sql)
# 通过cursor可使用fetchone()/fetchall()方法获取数据
data = g.db.fetchall()
print(data)
session:可以跨请求
import os
from flask import Flask, request, session
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
@app.route('/login')
def login():
username = request.args.get('user')
pwd = request.args.get('pwd')
if username and pwd:
session['auth'] = username
return '登录成功'
return '未登录'
@app.route('/')
def index():
if not session.get('auth'):
return '尚未登录'
return '这是首页'
@app.route('/logout')
def logout():
if session.get('auth'):
session.pop('auth',None)
return '登出'
if __name__ == '__main__':
app.run(debug=True)
效果:
session.permanent=True:设置才有过期时间,否则浏览器关闭就过期。
current_app:
当我们想从app之外的地方去访问app的一些属性和资源,可以使用current_app.xxx去访问,例如:current_app.config可以访问app.config的属性数据,而且current_app还具有线程隔离的作用,不会在多线程访问app时出现数据紊乱的问题。