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 提供的钩子函数非常灵活,你可以根据需要选择合适的钩子来插入自定义逻辑。

相关推荐
南山乐只3 分钟前
【Spring AI 开发指南】ChatClient 基础、原理与实战案例
人工智能·后端·spring ai
小鸡脚来咯16 分钟前
python虚拟环境
开发语言·python
龘龍龙25 分钟前
Python基础(九)
android·开发语言·python
大学生毕业题目1 小时前
毕业项目推荐:91-基于yolov8/yolov5/yolo11的井盖破损检测识别(Python+卷积神经网络)
python·yolo·目标检测·cnn·pyqt·井盖破损
XLYcmy1 小时前
TarGuessIRefined密码生成器详细分析
开发语言·数据结构·python·网络安全·数据安全·源代码·口令安全
努力的小雨1 小时前
从“Agent 元年”到 AI IDE 元年——2025 我与 Vibe Coding 的那些事儿
后端·程序员
weixin_433417672 小时前
Canny边缘检测算法原理与实现
python·opencv·算法
梨落秋霜2 小时前
Python入门篇【元组】
android·数据库·python
i小杨2 小时前
python 项目相关
开发语言·python
weixin_462446232 小时前
使用 Tornado + systemd 搭建图片静态服务(imgserver)
开发语言·python·tornado