zoukankan      html  css  js  c++  java
  • Flask_请求钩子(七)

    在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:

    • 在请求开始时,建立数据库连接;
    • 在请求开始时,根据需求进行权限校验;
    • 在请求结束时,指定数据的交互格式;

    为了让每个视图函数避免编写重复功能的代码,Flask提供了通用功能,即请求钩子。

    请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子:

    before_first_request

    功能:

    • 只在第一个请求之前调用,第一个请求之后不再调用。

    作用:

    • 可以在里面进行一些初始化操作,比如:连接数据库

    注意:

    • “第一次”不是指用户第一次发起请求,而是服务器第一次接收到请求。
    # 被该装饰器装饰的函数会在第一次请求之前调用。
    # 强调:第一次不是指用户第一次发起请求,而是服务器第一次接收到请求。
    # 作用:可以在此方法内部做一些初始化操作,比如连接数据库
    @app.before_first_request
    def before_first_request():
        print("before_first_request 被执行")

    before_request

    功能:

    • 在每次请求的之前调用

    作用:

    • 可以获取用户的session信息
    • 可以做一些请求校验,如果请求的校验不成功,可以使用return不执行视图函数

    注意点:

    • 使用了return ,响应的状态码就变成了200,如果用户输入不存在的路由,且校验不通过,将不会返回404
    # 被该装饰装饰的函数会在每一次请求之前调用
    # 作用:可以在这个请求中做一些请求校验,如果请求的校验不成功,直接return之后那么就不会执行视图函数
    @app.before_request
    def before_request():
        print("before_request 被执行")

    after_request

    功能:

    • 在每次请求之后,且视图函数被成功执行完之后调用
    • 需要传入一个参数,这个参数实际上为服务器的响应对象,并返回一个新的Response对象或者直接返回接受到的Response 对象

    作用:

    • 可以在此方法中对响应做最后一步统一的处理,比如修改headers信息
    # 被该装饰器装饰的函数会在视图被成功执行完之后调用,并且会把视图函数return的数据当做参数传入
    # 作用:可以在此方法中对响应做最后一步统一的处理,比如修改headers信息
    @app.after_request
    def after_request(resp):
        print("after_request 被执行")
        resp.headers["Content-Type"] = "application/json"
        return resp

    teardown_request

     功能:

    • 在每次请求之后调,无论视图函数是否执行成功,均调用

    作用:

    • 可以用来收集错误信息
    # 被该装饰器装饰的函数无论每一次请求是否成功都会调用
    # 会接受一个参数,若视图执行出错,参数是服务器出现的错误信息,反之,为None
    # 作用:可以用来收集错误
    @app.teardown_request
    def teardown_request(error):
        print("teardown_request 被执行")
        if error:
            print(F"错误URL:{request.url},错误原因:{error}")
    return app

    运行结果图:

     

     根据运行结果, 可以得出钩子函数在一次请求中的执行顺序, 如下图:

    附码:

    钩子管理文件,文件名为 app_init.py

    from flask import Flask, request
    
    
    def create_app():
        app = Flask(__name__)
    
        # 被该装饰器装饰的函数会在第一次请求之前调用。
        # 强调:第一次不是指用户第一次发起请求,而是服务器第一次接收到请求。
        # 作用:可以在此方法内部做一些初始化操作,比如连接数据库
        @app.before_first_request
        def before_first_request():
            print("before_first_request 被执行")
    
        # 被该装饰装饰的函数会在每一次请求之前调用
        # 作用:可以在这个请求中做一些请求校验,如果请求的校验不成功,直接return之后那么就不会执行视图函数
        @app.before_request
        def before_request():
            print("before_request 被执行")
    
        # 被该装饰器装饰的函数会在视图被成功执行完之后调用,并且会把视图函数return的数据当做参数传入
        # 作用:可以在此方法中对响应做最后一步统一的处理,比如修改headers信息
        @app.after_request
        def after_request(resp):
            print("after_request 被执行")
            resp.headers["Content-Type"] = "application/json"
            return resp
    
        # 被该装饰器装饰的函数无论每一次请求是否成功都会调用
        # 会接受一个参数,若视图执行出错,参数是服务器出现的错误信息,反之,为None
        # 作用:可以用来收集错误
        @app.teardown_request
        def teardown_request(error):
            print("teardown_request 被执行")
            if error:
                print(F"错误URL:{request.url},错误原因:{error}")
        return app

    视图函数文件

    # 请求钩子在 app_init.py 中被定义
    from app_init import create_app
    
    
    app = create_app()
    
    
    @app.route("/login/")
    def login():
        print("login视图被执行")
        return "登录成功"
    
    
    @app.route("/create/")
    def create():
        print("create视图被执行")
        return "创建成功"
    
    
    @app.route("/error/")
    def error():
        print("error视图被执行")
        a = 1/0
        return "ok"
    
    
    if __name__ == '__main__':
        app.run()

    参考:

    https://blog.csdn.net/dakengbi/article/details/94437972

    https://blog.csdn.net/f704084109/article/details/80932126

  • 相关阅读:
    pstree
    gvisor vfs2
    gvisor entersyscall exitsyscall
    gvisor在arm64下syscall.SIGILL信号处理
    SpringBlade 为id添加自增长属性
    SQL Server Update 一个列的数据为随机数
    SpringBlade Saber 关闭验证码
    SpringBlade Saber 用户列表的新增按钮 是怎么个显示原理
    SpringBlade Saber 切换标签页 不刷新
    SpringBlade 00 常见问题汇总
  • 原文地址:https://www.cnblogs.com/testlearn/p/14106288.html
Copyright © 2011-2022 走看看