Flask 应用程序上下文:app.app_context().push() 可以工作,但无法让“with app.app_context()”块工作

Ste*_*eve 8 flask

我是 Flask 的新手,只编写了一个相当简单的 Web 应用程序——没有数据库,只是一个航班搜索 API 的前端。一切都很好,但为了提高我的技能,我尝试使用应用程序工厂和蓝图重构我的代码。可以使用push()但无法阻止with工作。

fly_app/__init.py__
Run Code Online (Sandbox Code Playgroud)

我原来的代码:

from flask import Flask
from config import Config
import logging
from logging.handlers import RotatingFileHandler
import os

app = Flask(__name__)
app.config.from_object(Config)

if not app.debug:
    ...

from fly_app import routes, errors  # noqa
Run Code Online (Sandbox Code Playgroud)

我根据需要将该应用程序导入到其他模块。

现在该文件已被重构为以下内容并且似乎可以工作:

from flask import Flask
import logging
from logging.handlers import RotatingFileHandler
import os


def create_app():
    # create and configure the app
    app = Flask(__name__)
    app.config.from_mapping(
        SECRET_KEY=os.environ.get('SECRET_KEY', 'nice-try')
    )
    app.app_context().push()

    if not app.debug and not app.testing:
        ...

    from . import routes
    app.register_blueprint(routes.bp)

    return app
Run Code Online (Sandbox Code Playgroud)

我需要 app_context,以便我可以在其他模块中使用 current_app.static_folder 和 current_app.logger.exception() 。我读过使用with块,例如,

with app.app_context():
    init_db()
Run Code Online (Sandbox Code Playgroud)

优先于

app.app_context().push()
Run Code Online (Sandbox Code Playgroud)

Flask 文档中:“在 with 块中使用 app_context(),块中运行的所有内容都可以访问 current_app。”

我的问题:

  1. with该块与使用 有何不同或更好app.app_context().push()
  2. 使用push()是否相当于在我的原始代码中创建app一个全局变量,从而一事无成?
  3. 我无法弄清楚如何with在不引发“运行时错误:在应用程序上下文之外工作”的情况下使块正常工作。我已经尝试过该with块,包括:
    • app.static_folder
    • current_app(导入后)或current_app.[attr]
    • 使用 current_app 的特定 module.methods() 或属性

例如,我编写了两个自定义验证器——code_check 和currency_check——与从 模块flask_wtf.FlaskForm中派生的类一起使用forms.py。我无法将这些接受formfield位置参数放入 with 块中,因为它们未定义。

作为一个相对新手,尽管阅读了文档并搜索了互联网,但我显然不理解应用程序上下文是如何工作的。

Dav*_*ith 5

当刚接触 Flask 时,将多个来源的代码拼凑在一起会让人感到沮丧。我明白你的前进方向,并强烈建议你阅读 Miguel Grinberg 的Flask Mega 教程。它列出了一条可以让您更好地了解 Flask 工作原理的路径。

(提示:不需要app.app_context().push()in create_app()