zoukankan      html  css  js  c++  java
  • flask钩子函数

    请求钩子

    通过装饰器为一个模块添加请求钩子, 对当前模块的请求进行额外的处理. 比如权限验证.

    应用钩子函数

    before_first_request

    在对应用程序实例的第一个请求之前注册要运行的函数, 只会执行一次

    #: A lists of functions that should be called at the beginning of the
        #: first request to this instance.  To register a function here, use
        #: the :meth:`before_first_request` decorator.
        #:
        #: .. versionadded:: 0.8
        self.before_first_request_funcs = []
    
        @setupmethod
        def before_first_request(self, f):
            """Registers a function to be run before the first request to this
            instance of the application.
    
            .. versionadded:: 0.8
            """
            self.before_first_request_funcs.append(f) 

    将要运行的函数存放到before_first_request_funcs 属性中进行保存

    before_request

    在每个请求之前注册一个要运行的函数, 每一次请求都会执行

    #: A dictionary with lists of functions that should be called at the
       #: beginning of the request.  The key of the dictionary is the name of
       #: the blueprint this function is active for, `None` for all requests.
       #: This can for example be used to open database connections or
       #: getting hold of the currently logged in user.  To register a
       #: function here, use the :meth:`before_request` decorator.
       self.before_request_funcs = {} 
    
       @setupmethod
        def before_request(self, f):
            """Registers a function to run before each request."""
            self.before_request_funcs.setdefault(None, []).append(f)
            return f

    将要运行的函数存放在字典中, None 为键的列表中存放的是整个应用的所有请求都要运行的函数.
    after_request

    在每个请求之后注册一个要运行的函数, 每次请求都会执行. 需要接收一个 Response 类的对象作为参数 并返回一个新的Response 对象 或者 直接返回接受到的Response 对象

    #: A dictionary with lists of functions that should be called after
        #: each request.  The key of the dictionary is the name of the blueprint
        #: this function is active for, `None` for all requests.  This can for
        #: example be used to open database connections or getting hold of the
        #: currently logged in user.  To register a function here, use the
        #: :meth:`after_request` decorator.
        self.after_request_funcs = {}
    
        @setupmethod
        def after_request(self, f):
            """Register a function to be run after each request.  Your function
            must take one parameter, a :attr:`response_class` object and return
            a new response object or the same (see :meth:`process_response`).
    
            As of Flask 0.7 this function might not be executed at the end of the
            request in case an unhandled exception occurred.
            """
            self.after_request_funcs.setdefault(None, []).append(f)
            return f

    将要运行的函数存放在字典中, None 为键的列表中存放的是整个应用的所有请求都要运行的函数.

    teardown_request

    注册一个函数在每个请求的末尾运行,不管是否有异常, 每次请求的最后都会执行.

    #: A dictionary with lists of functions that are called after
        #: each request, even if an exception has occurred. The key of the
        #: dictionary is the name of the blueprint this function is active for,
        #: `None` for all requests. These functions are not allowed to modify
        #: the request, and their return values are ignored. If an exception
        #: occurred while processing the request, it gets passed to each
        #: teardown_request function. To register a function here, use the
        #: :meth:`teardown_request` decorator.
        #:
        #: .. versionadded:: 0.7
        self.teardown_request_funcs = {}
    
        @setupmethod
        def teardown_request(self, f):
            """Register a function to be run at the end of each request,
            regardless of whether there was an exception or not.  These functions
            are executed when the request context is popped, even if not an
            actual request was performed.
            """
            self.teardown_request_funcs.setdefault(None, []).append(f)
            return f

    将要运行的函数存放在字典中, None 为键的列表中存放的是整个应用的所有请求都要运行的函数.

    常用的钩子函数

    @before_first_request
    在对应用程序实例的第一个请求之前注册要运行的函数,只会运行一次

    @before_request
    在每个请求之前注册一个要运行的函数,每一次请求都会执行一次

    @after_request
    在每个请求之后注册一个要运行的函数,每次请求完成后都会执行。
    需要接受一个Response对象作为参数,并返回一个新的Response对象,或者返回接收的Response对象

    @teardown_request
    注册在每一个请求的末尾,不管是否有异常,每次请求的最后都会执行。

    @context_processor
    上下文处理器,返回的字典可以在全部的模板中使用

    @template_filter('xxxxxx')
    增加模板过滤器,可以在模板中使用该函数,后面的参数是名称,在模板中用到

    @errorhandler(400)
    发生一些异常时,比如404,500,或者抛出异常(Exception)之类的,就会自动调用该钩子函数
    1.发生请求错误时,框架会自动调用相应的钩子函数,并向钩子函数中传入error参数
    2.如果钩子函数没有定义error参数,就会报错
    3.可以使用abort函数来手动终止请求抛出异常,如果要是发生参数错误,可以abort(404)之类的

    from flask_lesson2.app import app
    from flask_lesson2.utils import myprint
    from flask import session, render_template
    
    myprint('hooks')
    
    
    @app.before_first_request
    def before_first_request():
        """
        在第一次启动服务器时会被调用
        """
        myprint('before_first_request')
    
    
    @app.before_request
    def before_request():
        """
        每一次请求之前被调用到
        """
        myprint('before_request')
    
    
    @app.after_request
    def after_request(resp):
        """
        每一次请求之后被调用
        :param resp:    这个参数是response对象
        :return:    需要返回一个response对象,可以是新的,也可以是传入进入的
        """
        myprint('after_request')
        return resp
    
    
    @app.teardown_appcontext
    def teardown_appcontext(e):
        """
        注册在每一个请求的末尾,不管是否有异常,每次请求的最后都会执行。
        :param e:
        """
        myprint('teardown_appcontext')
        myprint(e)
    
    
    @app.template_filter('uuuper')
    def template_filter(s):
        """
        自定义过滤器
        上面uuuper就是过滤器名称,在模板中使用,例如{{username}uuuper}}就是把字符串全部大写
        :param s: 传入进来的参数,可以有多个,根据你要的功能添加
        :return: 返回处理后的数据
        """
        myprint('template_filter')
    
        return s.upper()
    
    
    @app.context_processor
    def context_processor():
        """
        返回一个字典,字典中的值在模板任意地方都能使用,该函数被调用时在before_request之后
        after_request之前
        :return: 携带了需要的数据的字典
        """
        myprint('context_processor')
    
        context = {}
        username = session.get('username')
        context.update(username=username)
    
        return context
    
    
    @app.errorhandler(404)
    def errorhandler(e):
        """
        异常处理,可以根据不同的异常定制不同的处理方法
        :param e: 异常信息
        :return: 可以返回一个模板,例如404.html,告知用户错误信息等
        """
        myprint('error_handler,404')
        myprint(e)
        return render_template('index.html'), 404

    从结果上来看,七个钩子都被执行了.

    根据Blueprint 钩子函数的运行结果以及前面对应用的钩子函数的理解,

        推测1 : Blueprint 钩子函数其内部应该也是对某一个容器进行更改,
        推测2 : 按照打印顺序可以得出另一个推测, 如下图, 蓝图的请求钩子是在应用的请求钩子的基础上增加了自己的钩子,共同构成了蓝图的七个请求钩子.

     案例==>登陆验证

    
    
    required_login_list = ['/user/center','/user/change']
    @user_bp.before_app_first_request
    def first_request():
    print('before_app_first_request')
    @user_bp.before_app_request
    def before_request():
    # print('before_request',request.path)
    if request.path in required_login_list:
    id = session.get('uid')
    if not id:
    return render_template('users/login.html')
    else:
    user = User.query.get(id)
    g.user = user
    @user_bp.after_app_request
    def after_app_request(response):
    response.set_cookie('a','bbb',max_age=19)
    print('after_request_test')
    return response

    @user_bp.teardown_app_request
    def teardown_app_request(response):
    print('teardown_app_request')
    return response
     


    原文链接:https://blog.csdn.net/f704084109/article/details/80932126

    https://www.cnblogs.com/fengzi759/p/12152535.html

  • 相关阅读:
    (TOJ1004)渊子赛马
    (TOJ1063)养兔子
    (TOJ3260)Palindromes
    (TOJ1070)Least Common Multiple
    (TOJ1215)数据结构练习题——合并表
    (TOJ1481)C语言实验题——鞍点
    (TOJ1496)C语言实验题——字符过滤
    (TOJ1003)1、2、3、4、5...
    (TOJ1490)C语言实验题——合法的C标识符
    (TOJ2804)Even? Odd?
  • 原文地址:https://www.cnblogs.com/fat-girl-spring/p/15457940.html
Copyright © 2011-2022 走看看