Flask:闪现; 请求扩展;自定义中间件

一 .闪现

一 .什么是闪现

a 产生信息,传给 c 页面
但是用户访问a 页面以后,不是直接跳转到c,而是到b,或则是其他页面,但是用户访问c页面的时候,我希望把a给我的信息拿到

应用场景:假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息

二 使用

1.前提和注意点

1 如果要用flash就必须设置app.secret_key = 'asdfasdf',因为session是基于session的

2 在同一个路由视图函数中可以多次取值,但在一视图函数中取值过后再去另一个视图函数中在取就没有了

3 我们可以通过  flash('普通信息',category="分类名"),对信息做分类

4get_flashed_messages(with_categories=True,category_filter("error",))
with_categories以键值对的形式获取;我们设置闪现,category_filter=("error",)进行分类信息的过滤

2.具体使用

最简单使用

设置:flash('aaa')
取值:get_flashed_message()

复杂用法

from flask import Flask,flash,get_flashed_messages,request,redirect

app = Flask(__name__)
app.secret_key = 'asdfasdf'

@app.route('/index1')
def index():
    #(category="message", message))
    flash('超时错误',category="error")
    flash('普通信息',category="info")
    return "ssdsdsdfsd"
    # return redirect('/error')

@app.route('/error')
def error():
    data1 = get_flashed_messages(with_categories=True,category_filter=("error","info"))
    data2 = get_flashed_messages()
    data3 = get_flashed_messages(with_categories=True)
    data4 = get_flashed_messages(category_filter=("error","info"))
    print("data1",data1) # data1 [('error', '超时错误'), ('info', '普通信息')]
    print("data2",data2) # data2 ['超时错误', '普通信息']
    print("data3",data3) # data3 [('error', '超时错误'), ('info', '普通信息')]
    print("data4",data4) # data4 ['超时错误', '普通信息']
    return "错误信息"

if __name__ == '__main__':
    app.run()

二 请求扩展

链接:https://www.cnblogs.com/Hades123/p/11781182.html

1.before_request

类似于django中的process_request,在收到请求之后,进入视图函数之前,进行一些数据或者怎样的处理

  • 可写多个before_request函数
  • 视图函数之前从上往下执行的
  • 一旦有返回值,立马从下往上执行after_request,请求的视图函数不会执行,已经剩下的before_request不会执行
#基于它做用户登录认证
@app.before_request
def process_request(*args,**kwargs):
    if request.path == '/login':
        return None
    user = session.get('user_info')
    if user:
        return None
    return redirect('/login')

2.after_request

类比django中间件中的process_response,每一个请求之后绑定一个函数,如果请求没有异常

  • 可以写多个after_request函数
  • 所有的after_request是视图函数之后从下往上执行,和before_request相反
  • 无论 before_request有没有返回值,我的after_request都会执行
  • 必须接受response,而且必须返回response

@app.before_request
def process_request1(*args,**kwargs):
    print('process_request1 进来了')

@app.after_request
def process_response1(response):
    print('process_response1 走了')
    # after_request 必须返回 response
    return response

# 视图函数
@app.route('/index',methods=['GET'])
def index():
    print('index函数')
    return "Index"

if __name__ == '__main__':
    app.run()

3 before_first_request

项目启动后,接受到的第一个请求之前,会执行该函数,后面就不会在执行,除非重启项目

比如:数据库的连接,初始化操作

from flask import Flask,request
app = Flask(__name__)
app.debug = True

# 内部其实就有个判断,初始值是FALSE,第一次执行后将值改变为True,以后判断后就不执行了
@app.before_first_request
def before_first_request2():
    print('before_first_request2')

if __name__ == '__main__':
    app.run()

4 teardown_request

每一个请求之后绑定一个函数,即使遇到了异常 ,也不会终止函数的执行

  • 这是e 是接收我服务器抛出的异常
  • 无论我服务器有没有错误,都会执行该函数,并且是在请求之后(after_request)执行
  • 虽然能接收异常,但是没有办法处理异常
  • 可以用来监控程序是否报错,记录日志
如论有无异常都执行,如果没有异常这个e就是None
@app.teardown_request
def ter(e):
    # if e:
        #logingh
    # return "wo si l"
    print("我抛异常")

5.errorhandler

定制错误信息:

  • 参数的中值为错误码
  • 当服务器抛出对应状态码的异常,就会执行该函数,是在before_request和after_request中间执行
  • 并且该函数可以处理异常,让用户无法感知,服务器错误
  • 每一个错误码,都需要一个对应的函数进行处理
我是请求之前1
我是请求之前2
111 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
我是请求之后下2
我是请求之后上1
teardown_request
@app.errorhandler(404)
def error_404(arg):
    print(111,arg)
    return "404错误了"

6.template_global

from flask import Flask,request
app = Flask(__name__)
app.debug = True

# 这就是基于请求扩展的 定制模板方法
# 相对于在模板里定制了一个函数

@app.template_global()
def sb(a1, a2):
    return a1 + a2

# 在HTML里直接调用的方式(不需要返回html页面进行传递函数名):{{sb(1,2)}}

if __name__ == '__main__':
    app.run()

7.template_filter

过滤器

from flask import Flask,request
app = Flask(__name__)
app.debug = True

# 这就是基于请求扩展的 定制模板方法
@app.template_filter()
def db(a1, a2, a3):
    return a1 + a2 + a3

#在HTML里调用的方式如下:
# {{ 1|db(2,3)}   # 参数 a1 = 1,是第一个参数; a2=2 是第二个参数;   a3=3 是第三个参数

if __name__ == '__main__':
    app.run()

三 .自定义中间件

 #1我们发现当执行app.run方法的时候,最终执行run_simple,最后执行app(),也就是在执行app.__call__方法 
    #2 在__call__里面,执行的是self.wsgi_app().那我们希望在执行他本身的wsgi之前做点事情。
    #3 所以我们先用Md类中__init__,保存之前的wsgi,然后我们用将app.wsgi转化成Md的对象。
    #4 那执行新的的app.wsgi_app,就是执行Md的__call__方法。
    #把原来的wsgi_app替换为自定义的,
from flask import Flask
app = Flask(__name__)

class MyMiddleware:
def __init__(self,wsgi_app):
self.wsgi_app=wsgi_app

def __call__(self,environ, start_response):

print("进入视图函数之前")
res=self.wsgi_app(environ, start_response)
print("离开视图函数之后")
return res

@app.route('/index')
def index():
return "ok"

if __name__ == '__main__':
app.wsgi_app = MyMiddleware(app.wsgi_app)

app.run()
原文地址:https://www.cnblogs.com/tfzz/p/11845681.html