flask 请求扩展(钩子函数)和中间件

一、钩子函数定义

钩子函数:是在一个事件触发的时候,捕获到它的数据,对他进行处理,再将处理后的数据返回

二、Flask常用的请求扩展

1、before_first_request

项目启动后第一次请求的时候执行

# 项目启动后,发起的第一次请求会走它
@app.before_first_request
def first():
    print('第一次发起请求')
    return 'first_request请求'

2、before_request

每次请求来之前执行,类似于django的process_request,可以应用在校验用户的场景

注意:如果有多个before_request,执行顺序从上往下,如果多个before_request有一个return 返回值,那么它接下来的before_request以及它装饰的视图函数将不会再执行

@app.before_request
def login_d():
   #如果没有cookies值,则跳转到登陆界面重新登陆
    cookies=request.cookies
    if cookies is None:
        return redirect('/login')
    else:
        return '我来了,请开门'

@app.before_request
def login_d1():
    print('我来了1')
    return '我来了1,请开门'
# 注意:before_request是从上往下执行,第一个有return返回值,所以第二个before_request不会再走

3、after_reqeust

每次请求后执行,如果请求出现异常,则不会执行,类似Django的process_response,执行顺序是从下往上

@app.after_request
def after(response):
    print('我走了')
    return response
@app.after_request
def after1(response):
    print('我走了1')
    return response
# 注意:是先执行after1再执行after,因为它的执行顺序是从下往上

4、teardown_request

视图函数执行完,都会走它,一般用来记录错误日志,如下例子,index页面出错了,它捕获到错误e

注意:必须用带参数,参数可以自定义

# 视图函数执行完会走它,一般用来记录出错日志
@app.teardown_request
def tear(e):
    print(e)
    print('我关门了')
@app.route('/index')
def index():
    print('aaa')
    ad
    return 'test'

5、errorhandler监听错误状态码

通过监听http错误状态码(也就是4和5系列的状态码),进监听的状态码进行处理

@app.errorhandler(400)
def status(error):
    print(error)
    return 'http 400错误'

6、template_global全局模板标签

@app.template_global()
def add(a,b):
    return a+b

# 前端调用
{{add(1,2)}}

7、template_filter全局过滤器

@app.template_filter()
def add_filter(a1, a2, a3):
    return a1 + a2 + a3

# 前端调用
{{1|add_filter(2,3,4)}}

总结:有了全局过滤器和模板标签,就不用再传一个函数给模板调用了。before_request和after_request跟Django的process_request和process_response中间,本质基本一样

 三、中间件

本质:就是重写app的__call__方法,还是调用原来的app.wsgi_app方法,只不过是在调用wsgi_app方法前后添加一些自己的代码功能

创建中间件类过程:先创建一个中间件类,通过__init__初始化,将wsgi_app处理成中间件类的属性,再重写__call__方法,再__call__方法中书写中间件代码,将__call__方法的参数传给属性wsgi_app(*args,**kwargs)。

使用: 将中间件类实例化的对象,赋值给app.wsgi_app

注意,一定要把原来的app.wsgi_app方法传给中间件类初始化

          重写的__call__方法本质还是在执行原来的call方法,只不过是在执行wsgi_app方法前后,添加一些自定制的代码

例子

from flask import Flask

app=Flask('__name__')

class Mindle(object):
    def __init__(self,wsgi_app):
        self.wsgi_app=wsgi_app
    def __call__(self, *args, **kwargs):
        '''
        这里书写中间件代码,还没对请求处理的时候
        '''
        obj=self.wsgi_app(*args,**kwargs)
        '''
        这里书写中间件代码,请求处理好的时候
        '''
        return obj

if __name__=='__main__':
  # 将原来的app.wsgi_app方法传给Midle中间件类,实例化成类的属性 app.wsgi_app
=Mindle(app.wsgi_app) app.run()
不将就
原文地址:https://www.cnblogs.com/nq31/p/14337225.html