zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    Shell编程进阶 1.2 shell结构及执行
    LNMP 1.6 常见的502问题解决
    关于贴图看不到。显示是白色或者其他。
    windows 任务栏图标宽度固定
    Install Oracle Java JDK/JRE 7u55 on Fedora 20/19, CentOS/RHEL 6.5/5.10
    盘点天龙历史:七年以来所有资料片
    linux shell 逻辑运算符、逻辑表达式详解
    vim 把满足条件的数字进行加上一些数字
    win7 一些快捷系统工具命令
    Linux下用C读取配置文件。类似ini这样。
  • 原文地址:https://www.cnblogs.com/tfzz/p/11845681.html
Copyright © 2011-2022 走看看