flask请求钩子
Flask的请求钩子指的是在执行视图函数前后执行的一些函数,我们可以在这些函数里面做一些操作。
Flask利用装饰器给我们提供了四种钩子函数。
before_first_request:在处理第一个请求前执行。比如链接数据库操作
before_request:在每次请求前执行。比如权限校验
after_request:每次请求之后调用,前提是没有未处理的异常抛出
teardown_request:每次请求之后调用,即使有未处理的异常抛出
Flask里面的钩子跟Django里面的中间件类似。
在第一次请求之前运行
@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: 就是前面的请求处理完毕之后, 返回的响应数据,前提是视图函数没有出现异常
# 如果需要对响应做额外处理,可以再这里进行
# json.dumps 配置请求钩子
# response.headers["Content-Type"] = "application/json"
print('after_request')
return response
无论视图函数是否出现异常,每一次请求之后都会调用,会接受一个参数,参数是服务器出现的错误信息
@app.teardown_request
def teardown_request(error):
print('teardown_request: error %s' % error)
我们在浏览器第一次访问:
before_first_reques
t before_request
视图函数执行
after_reques
t teardown_request:
error None
我们在刷新浏览器试一下:
before_request
视图函数执行
after_request
teardown_request: error None
上下文
request 和 session 都属于请求上下文对象。
request:封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user’),获取的是get请求的参数。
session:用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name’] = user.id,可以记录用户信息。还可以通过session.get(‘name’)获取用户信息。
请求上下文
将初始的初始request封装RequestContext对象ctx
def request_context(self, environ):
return RequestContext(self, environ)
借助LocalStack对象将ctx放到Local对象中
_request_ctx_stack = LocalStack()
_request_ctx_stack.push(self)
导入from flask import request,其中request对象是LocalProxy类的实例化对象
request = LocalProxy(partial(_lookup_req_object, 'request'))
应用上下文
from flask import g:在一次请求周期里,用于存储的变量,便于程序员传递变量的时候使用。
g变量是解决我们在一次请求过程传递参数的问题,我们可以往g变量塞很多属性,在同一次请求中,可以从另一个函数中取出。当然也可以用函数参数这种方法解决,g变量适用于参数多的情况。
蓝图
使用装饰器解决
例如我们把上面的home视图抽出来,放到单独的一个home.py文件中。在此文件只写一个没有被装饰器装饰的视图函数。
def home():
return 'home page'
然后在Flask的启动程序文件中,把home视图在重新用装饰器装饰起来。
from home import home
# 装饰home视图
app.route('/home')(home)
什么是蓝图
蓝图:用于实现单个应用的视图、模板、静态文件的集合。
蓝图就是模块化处理的类。
简单来说,蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能。 在Flask中,使用蓝图可以帮助我们实现模块化应用的功能。
Flask中的蓝图有点像Django框架的app的意思。就是把一个项目模块化,每个模块所用的视图、静态文件、模板放在一个盒子里。
使用蓝图
在使用蓝图之前,我们需要先创建蓝图,继续那我们上面的home视图函数举例,把home.py文件里面的代码修改如下:
from flask import Blueprint
# app_home值蓝图的名称,
# __name__指蓝图所在模块
app_home = Blueprint('app_home', __name__)
# 注册蓝图路由
@app_home.route('/home')
def home():
return 'home page'
Flask的启动程序文件中,导入蓝图并注册蓝图:
#导入蓝图
from home import app_home
# 注册蓝图
app.register_blueprint(app_home)
在Flask中用url_prefix可以给蓝图模块添加一个共同的地址。
app.register_blueprint(app_home, url_prefix='/user')
以蓝图模块导入
把Flask中的蓝图用python中包的概念管理起来。
在__init__.py文件中创建蓝图:
from flask import Blueprint
# app_home值蓝图的名称,
# __name__指蓝图所在模块
app_home = Blueprint('app_home', __name__)
from .views import home
在views.py文件中注册蓝图路由:
from . import app_home
# 注册蓝图路由
@app_home.route('/home')
def home():
return 'home page'
在Flask启动文件导入蓝图:
from flask import Flask
# 导入蓝图
from home import app_home
app = Flask(__name__)
# 注册蓝图 app.register_blueprint(app_home, url_prefix='/user')
@app.route('/')
def index():
return 'index page'
if __name__ == '__main__':
# 0.0.0.0代表任何能代表这台机器的地址都可以访问 app.run(host='0.0.0.0', port=5000, debug=True) # 运行程序
我们修改一下home的视图函数,改成加载模板:
from . import app_home
from flask import render_template
# 注册蓝图路由
@app_home.route('/home')
def home():
return render_template('home.html')
二、g对象
g:global
- g对象是专门用来保存用户的数据的。
- g对象在一次请求中的所有的代码的地方,都是可以使用的。