Flask 请求的生命周期

一、请求生命周期

Flask 请求的生命周期涉及到整个处理请求的过程,包括请求的接收、视图函数的执行、响应的生成和发送等。以下是一个简要的 Flask 请求生命周期的概述:

  • WSGI 服务器调用 Flask 对象,该对象调用 Flask.wsgi_app() 。

  • 一个 RequestContext 对象被创建,将 WSGI environ 字典转换为一个 Request 对象。它还创建一个 AppContext 对象。

  • app context 被推送,这使得 current_app 和 g 可用。

  • 发送 appcontext_pushed 信号。

  • request context 被推送,这使得 request 和 session 可用。

  • 会话被打开,使用应用程序的 session_interface ,一 个 SessionInterface 实例,载入所有现存的会话数据。

  • 将 URL 与在应用设置期间使用 route() 装饰器注册的 URL 规则进行匹配。如果没有匹配项,则错误(通常是 404 、405 或重 定向)被存储以供以后处理。

  • 发送 request_started 信号。

  • 调用所有 url_value_preprocessor() 装饰的函数。

  • 调用所有 before_request() 装饰的函数。如果有任何返回值,那么就立即被视为响应。

  • 如果 URL 在几个步骤前与路由不匹配,则现在会引发该错误。

  • 与匹配的 URL 关联的 route() 装饰器视图函数 被调用并返回要用作响应的值。

  • 如果到目前为止的任何步骤引发了异常,并且有一个 errorhandler() 装饰器函数与异常类或 HTTP 错误代码匹 配,那么调用它处理错误并返回响应。

  • 不管是请求前函数、视图或错误处理程序,都会返回一个响应值,并被转换为 Response 对象。

  • 任何 after_this_request() 装饰的函数都会被调用,然后被清除。

  • 任何 after_request() 装饰的函数都会被调用,它们可以 修改响应对象。

  • 会话被保存,使用应用程序的:attr:~.Flask.session_interface 装饰 函数来持久化任何已修改的会话数据。

  • request_finished 信号被发送。

  • 如果到目前为止的任何步骤引发了一个异常,并且没有被错误处理函数处 理,那么现在会被处理。 HTTP 异常会使用对应的状态代码作为响应,其他的异常被转换为一个通用的 500 响应。 got_request_exception 信号被发送。

  • 响应对象的状态、头部信息和正文被返回给 WSGI 服务器。

  • 任何 teardown_request() 装饰的函数都被调用。

  • request_tearing_down 信号被发送。

  • 请求上下文被弹出, request 和 session 不再可用。

  • 任何 teardown_appcontext() 的装饰函数都被调用。

  • appcontext_tearing_down 信号被发送。

  • 应用上下文被弹出, current_app 和 g 不再可用。

  • appcontext_popped 信号被发送。

还有更多的装饰器和定制点,但它们并不是每个请求生命周期都有。它们更多的是针对在请求过程中可能使用的某些东西,如模板、构建URL 或处理 JSON 数据。

二、钩子函数

上文提到了多个Flask 提供的多个钩子函数,这些钩子函数允许你在请求处理的不同阶段插入自定义逻辑。以下是一些常用的 Flask 钩子函数的用法:

  1. before_first_request:

    • 在处理第一个请求之前执行一次,通常用于初始化应用。
    python 复制代码
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.before_first_request
    def before_first_request():
        print("This runs before the first request.")
  2. before_request:

    • 在每次请求之前执行,可用于执行一些全局的预处理工作。
    python 复制代码
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.before_request
    def before_request():
        print("This runs before each request.")
  3. after_request:

    • 在每次请求之后执行,可用于修改响应对象。
    python 复制代码
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.after_request
    def after_request(response):
        print("This runs after each request.")
        return response
  4. teardown_request:

    • 在每次请求之后执行,无论是否发生异常。通常用于清理资源。
    python 复制代码
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.teardown_request
    def teardown_request(exception):
        print("This runs after each request, even if an exception occurred.")
  5. before_render_template:

    • 在渲染模板之前执行,可以用于在模板渲染之前注入一些全局数据。
    python 复制代码
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    @app.before_render_template
    def before_render_template(template, context):
        print("This runs before rendering the template.")
        context['global_variable'] = 'I am a global variable.'
  6. template_rendered:

    • 在模板渲染之后执行,用于执行一些与模板渲染相关的操作。
    python 复制代码
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    @app.template_rendered
    def template_rendered(template, context):
        print("This runs after rendering the template.")
  7. url_value_preprocessor:

    • 注册 URL 变量预处理函数,可以在请求处理之前对 URL 变量进行处理。
    python 复制代码
    from flask import Flask, url_for
    
    app = Flask(__name__)
    
    @app.url_value_preprocessor
    def url_value_preprocessor(endpoint, values):
        print("This runs before processing the URL values.")
        # You can modify the values dictionary here.

这只是一小部分 Flask 钩子函数的示例,Flask 提供的钩子函数非常灵活,你可以根据需要选择合适的钩子来插入自定义逻辑。

相关推荐
云和数据.ChenGuang6 分钟前
print(f“a+b=“,result) print(f“a+b={result}“)区别
java·前端·人工智能·python·深度学习
2601_9628857216 分钟前
如何用 Python 算最大回撤和回撤恢复期?
java·数据库·python
Want59532 分钟前
Python大雪纷飞①
开发语言·python·数学建模
程序员清风44 分钟前
Python 数据可视化入门:Matplotlib 核心用法
python·信息可视化·matplotlib
溪语流沙1 小时前
【Web全栈进阶】前端对接新契约:信封解包 + 统一错误处理
前端·vue.js·python·状态模式·fastapi
Python图像识别1 小时前
56-【2027毕设】YOLO11X光安检危险物品检测系统 - Python完整源码+PyQt5界面+训练模型+数据集
python·qt·课程设计
黄鹂鸟科技1 小时前
进销存系统设计要点:从采购计划、库存监控到成本核算
后端·物联网·系统架构
winfredzhang1 小时前
从零实现“照片按地理位置显示在矢量地图上”:Flask + SQLite + Leaflet 全栈实战
python·sqlite·flask
撸串-研究生2 小时前
基于Spring Boot的智慧社区垃圾分类与回收系统的设计与实现【附源码】
spring boot·后端·分类·垃圾分类·社区管理
外收内放2 小时前
Python基础语法练习题(72)
开发语言·python