zoukankan      html  css  js  c++  java
  • flask总结03

    一:flask的请求勾子

    01:钩子概念说明:

    在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:
    
        在请求开始时,建立数据库连接;
    
        在请求开始时,根据需求进行权限校验;
    
        在请求结束时,指定数据的交互格式;
    
    为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子。
    
    请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子:
    
        before_first_request
    
            在处理第一个请求前执行
    
        before_request
    
            在每次请求前执行
    
            如果在某修饰的函数中返回了一个响应,视图函数将不再被调用
    
        after_request
    
            如果没有抛出错误,在每次请求后执行
    
            接受一个参数:视图函数作出的响应
    
            在此函数中可以对响应值在返回之前做最后一步修改处理
    
            需要将参数中的响应在此参数中进行返回
    
        teardown_request:
    
            在每次请求后执行
    
            接受一个参数:错误信息,如果有相关错误抛出
    

    02:案例代码

    from flask import Flask
    from settings.dev import DevConfig
    
    app = Flask(__name__)
    
    # 项目配置
    app.config.from_object(DevConfig)
    
    
    @app.before_first_request  # 第一次请求之前
    def before_first_request():
        print("--before_first_request--")
        print("系统初始化就执行这个钩子方法")
        print("会在接收到第一个客户端请求时,执行这里的代码")
    
    
    @app.before_request  # 每一次请求之前
    def before_request():
        print("----before_request----")
        print("每一次接收到客户端请求时,执行这个钩子方法")
        print("一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据")
    
    
    @app.after_request
    def after_request(response):
        print("----after_request----")
        print("在处理请求以后,执行这个钩子方法")
        print("一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作")
    
        response.headers["Content-Type"] = "application/json"  # 指定响应体的返回格式是json
    
        # 必须返回response
        return response
    
    
    @app.route("/test00")
    def index22():
        print("index 视图函数")
        print("index 被执行了")
    
        return "视图函数index被执行"
    
    
    
    if __name__ == '__main__':
        app.run()

    案例打印结果:

    第一次请求时打印的结果:

    --before_first_request--
    系统初始化就执行这个钩子方法
    会在接收到第一个客户端请求时,执行这里的代码
    ----before_request----
    每一次接收到客户端请求时,执行这个钩子方法
    一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据
    index 视图函数
    index 被执行了
    ----after_request----
    在处理请求以后,执行这个钩子方法
    一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作
    View Code

    第二次请求时的打印结果

    ----before_request----
    每一次接收到客户端请求时,执行这个钩子方法
    一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据
    index 视图函数
    index 被执行了
    ----after_request----
    在处理请求以后,执行这个钩子方法
    一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作
    View Code

    二:flask的异常捕获

    01:主动主动抛出HTTP异常(需要引入abort )

    案例代码:
    from flask import Flask,abort
    from settings.dev import DevConfig
    
    app = Flask(__name__)
    
    # 项目配置
    app.config.from_object(DevConfig)
    
    
    @app.route("/testyy")
    def index44():
        abort(400)
    
        return "abort() 状态码报错测试"
    
    if __name__ == '__main__':
        app.run()

    浏览器运行后的结果显示:(不同的转台吗显示不同的报错内容)

    抛出状态码的话,只能抛出 HTTP 协议的错误状态码

    400

    500

     

    02:捕获异常,错误

    自定义异常信息案例代码:

    from flask import Flask,abort
    from settings.dev import DevConfig
    
    app = Flask(__name__)
    
    # 项目配置
    app.config.from_object(DevConfig)
    
    
    #自定义异常信息
    @app.errorhandler(500)
    def internal_server_error(e):
        return "<h1>服务器搬家。。。</h1>"
    
    @app.route("/testqq")
    def index55():
        print("自定义异常错误信息")
        abort(500)
    
        return "自定义异常测试"
    
    if __name__ == '__main__':
        app.run()

    案例显示结果:

     03:捕获指定异常(raise   Exception)

    案例代码

    from flask import Flask,abort
    from settings.dev import DevConfig
    
    app = Flask(__name__)
    
    # 项目配置
    app.config.from_object(DevConfig)
    
    @app.errorhandler(Exception)
    def zero_division_error(e):
    
        return "除数不能为0"
    
    
    @app.route("/testtt")
    def testtt():
    
        print("testtt被执行")
        raise  Exception(zero_division_error)
        return "testtt被执行了。。。"
    
    if __name__ == '__main__':
        app.run()

    案例显示结果:

     三:flask的上下文

    01:上下文的理解

    作以及下文即将要执行的逻辑,可以决定在当前时刻下可以使用到的变量,或者可以完成的事情。
    
    Flask中有两种上下文,请求上下文(request context)和应用上下文(application context)。
    
    Flask中上下文对象:相当于一个容器,保存了 Flask 程序运行过程中的一些信息。
    
    
    1. *application* 指的就是当你调用`app = Flask(__name__)`创建的这个对象`app`;
    2. *request* 指的是每次`http`请求发生时,`WSGI server`(比如gunicorn)调用`Flask.__call__()`之后,在`Flask`对象内部创建的`Request`对象;
    3. *application* 表示用于响应WSGI请求的应用本身,*request* 表示每次http请求;
    4. *application*的生命周期大于*request*,一个*application*存活期间,可能发生多次http请求,所以,也就会有多个*request*

    02:请求上下文 (request context) 和应用上下文 (application context)

    请求上下文 (request context):

    在 flask 中,可以直接在视图函数中使用 **request** 这个对象进行获取相关数据,而 **request** 就是请求上下文的对象,保存了当前本次请求的相关数据,
    请求上下文对象有:request、session
    - request - 封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get('user'),获取的是get请求的参数。 - session - 用来记录请求会话中的信息,针对的是用户信息。举例:session['name'] = user.id,可以记录用户信息。还可以通过session.get('name')获取用户信息。

    应用上下文(application context):

    它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy。
    它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。 应用上下文对象有:current_app,g

    两者区别:

    - 请求上下文:保存了客户端和服务器交互的数据
    - 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等

     四:Flask-Script 扩展

    01:安装Flask-Script

    pip install flask-script

    02:集成 Flask-Script到flask应用中

    from flask import Flask
    from flask_script import Manager
    
    app = Flask(__name__)
    
    # 把 Manager 类和应用程序实例进行关联
    manager = Manager(app)
    
    @app.route('/')
    def index():
        return 'hello world'
    
    if __name__ == "__main__":
        manager.run()

    03: 增加一个命令行,当我们执行 python manage.py test的时候,也会启动服务端

    代码:

    from flask import Flask
    from settings.dev import DevConfig
    
    from flask_script import Manager, Command
    
    app = Flask(__name__)
    
    # 项目配置
    app.config.from_object(DevConfig)
    
    manage = Manager(app)
    
    
    # 自定义命令行
    class Hello(Command):
        """打印hello的自定义命令"""
    
        def run(self):
            print("hello 命令执行了...")
    
    
    manage.add_command("test", Hello())
    
    
    @app.route("/mag")
    def magtest():
        return "Hello tom!"
    
    
    if __name__ == '__main__':
        # app.run()   # 原来的启动方式
        manage.run()



    通过查询可以看到我么增加的一个命令行:

    但是在terminal终端执行的时候,一直会报错显示:

    SyntaxError: Non-ASCII character 'xe9' in file manage.py on line 8, but no encoding declared; see http://python.org/dev/peps/p
    ep-0263/ for details

    待解决。。。

  • 相关阅读:
    win7 重装 docker 启动后无法启动错误解决
    ASP.NET MVC 播放远程服务器上的MP3文件
    ubuntu+mono+PetaPoco+Oracle+.net 程序部署
    .NET Core 2.0 问题杂记
    博客园挂了吗?
    Content-Type: application/vnd.ms-excel">
    Storm
    Razor语法
    类型后面加问号 int?
    Apache vue site configuration
  • 原文地址:https://www.cnblogs.com/one-tom/p/10673261.html
Copyright © 2011-2022 走看看