应用程序上下文在请求,CLI命令或其他活动期间跟踪应用程序级数据。而不是将应用程序传递给每个函数,而是访问current_app 和g 代理。
这类似于请求上下文 ,它在请求期间跟踪请求级数据。当推送请求上下文时,推送相应的应用程序上下文。
上下文的目的
Flask 应用程序对象具有诸如config 之类的属性,这些属性对于在视图和CLI命令 中进行访问很有用。但是,在项目中的模块中导入app
实例很容易出现循环导入问题。使用应用工厂模式 或编写可重复使用的蓝图 或扩展 时,根本不会导入app
实例。
Flask使用 应用程序上下文 解决了这个问题。您可以使用current_app 代理,而不是直接引用应用程序,该代理指向处理当前活动的应用程序。
Flask在处理请求时自动 推送 应用程序上下文。视图函数,错误处理程序以及在请求期间运行的其他函数将具有对 current_app 的访问权限。
使用@app.cli.command()
运行在 Flask.cli 中注册的CLI命令时,Flask还会自动推送应用程序上下文。
上下文的生命周期
必要时创建并销毁应用程序上下文。当Flask应用程序开始处理请求时,它会pushes应用程序上下文和请求上下文 。当请求结束时,它会pops请求上下文,然后pops应用程序上下文。通常,应用程序上下文与请求具有相同的生命周期。
有关上下文如何工作以及请求的完整生命周期的更多信息,请参阅请求上下文。
手动Push一个上下文
如果您尝试在应用程序上下文之外访问current_app 或使用它的任何内容,您将收到以下错误消息:
|
|
如果在配置应用程序时发现错误,例如初始化扩展时,您可以手动push上下文,因为您可以直接访问app
。在with
块中使用 app_context() ,块中运行的所有内容都可以访问 current_app 。
|
|
如果您在代码中的其他位置看到与配置应用程序无关的错误,则很可能表示您应将该代码移动到视图函数或CLI命令中。
存储数据
应用程序上下文是在请求或CLI命令期间存储公共数据的好地方。Flask为此提供了g object 。它是一个简单的命名空间对象,其生命周期与应用程序上下文相同。
注意:
g名称代表“全局”,但这指的是在上下文中是全局的数据。上下文结束后g上的数据丢失,并且它不是在请求之间存储数据的合适位置。使用 会话(session) 或数据库跨请求存储数据。
g的常见用途是在请求期间管理资源。
- 如果资源X不存在,则
get_X()
创建资源X
,将其缓存为g.X
. - 如果资源存在,
teardown_X()
将关闭或以其他方式释放资源。它被注册为 teardown_appcontext() 处理程序。
例如,您可以使用此模式管理数据库连接:
|
|
在请求期间,每次调用get_db()
都将返回相同的连接,并在请求结束时自动关闭。
您可以使用 LocalProxy 从get_db()
创建一个新的本地上下文:
|
|
访问db
将在内部调用get_db
,方法与 current_app 的工作方式相同。
如果您正在编写扩展名,则应为用户代码保留 g 。您可以将内部数据存储在上下文中,但请确保使用足够唯一的名称。使用_app_ctx_stack.top 访问当前上下文。有关更多信息,请参阅Flask Extension Development。
事件和信号
当弹出应用程序上下文时,应用程序将调用teardown_appcontext() 注册的函数。