首页 > 解决方案 > Flask 应用程序上下文:app.app_context().push() 有效,但无法让“with app.app_context()”块工作

问题描述

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

fly_app/__init.py__

我的原始代码:

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

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

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

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

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

with app.app_context():
    init_db()

优先于

app.app_context().push()

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

我的问题:

  1. with块与 using 有何不同或更好 app.app_context().push()
  2. 使用push()相当于app在我的原始代码中创建一个全局变量,从而什么也没做?
  3. 我无法弄清楚如何在with不引发“RuntimeError:在应用程序上下文之外工作”的情况下让块工作。我试过的with块包括:
    • app.static_folder
    • current_app(导入后)或current_app.[attr]
    • 使用 current_app 的特定 module.methods() 或属性

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

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

标签: flask

解决方案


Flask 新手时将来自多个来源的代码拼凑在一起是一种挫败感。我看到了您前进的方向,强烈建议您通读 Miguel Grinberg 的Flask Mega 教程。它提供了一条路径,可以让您更好地了解 Flask 的工作原理。

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


推荐阅读