返回介绍

Blueprints

发布于 2025-01-02 21:53:56 字数 4832 浏览 0 评论 0 收藏 0

在 Flask 中,blueprint 是代表应用子集的逻辑结构。 blueprint 可以包括路由,视图函数,表单,模板和静态文件等元素。 如果在单独的 Python 包中编写 blueprint,那么你将拥有一个封装了应用特定功能的组件。

Blueprint 的内容最初处于休眠状态。 为了关联这些元素,blueprint 需要在应用中注册。 在注册过程中,需要将添加到 blueprint 中的所有元素传递给应用。 因此,你可以将 blueprint 视为应用功能的临时存储,以帮助组织代码。

错误处理 Blueprint

我创建的第一个 blueprint 用于封装对错误处理程序的支持。 该 blueprint 的结构如下:

app/
    errors/                             <-- blueprint package
        __init__.py                     <-- blueprint creation
        handlers.py                     <-- error handlers
    templates/
        errors/                         <-- error templates
            404.html
            500.html
    __init__.py                         <-- blueprint registration

实质上,我所做的是将 app/errors.py 模块移动到 app/errors/handlers.py 中,并将两个错误模板移动到 app/templates/errors 中,以便将它们与其他模板分开。 我还必须在两个错误处理程序中更改 render_template() 调用以使用新的 errors 模板子目录。 之后,我将 blueprint 创建添加到 app/errors/ init .py 模块,并在创建应用实例之后,将 blueprint 注册到 app/ init .py 。

我必须提一下,Flask blueprints 可以为自己的模板和静态文件配置单独的目录。 我已决定将模板移动到应用模板目录的子目录中,以便所有模板都位于一个层次结构中,但是如果你希望在 blueprint 中包含属于自己的模板,这也是支持的。 例如,如果向 Blueprint() 构造函数添加 template_folder='templates' 参数,则可以将错误 blueprint 的模板存储在 app/errors/templates 目录中。

创建 blueprint 与创建应用非常相似。 这是在 blueprint 的 ___init__.py 模块中完成的:

app/errors/__init__.py :错误 blueprint。

from flask import Blueprint

bp = Blueprint('errors', __name__)

from app.errors import handlers

Blueprint 类获取 blueprint 的名称,基础模块的名称(通常在 Flask 应用实例中设置为 __name__ )以及一些可选参数(在这种情况下我不需要这些参数)。 Blueprint 对象创建后,我导入了 handlers.py 模块,以便其中的错误处理程序在 blueprint 中注册。 该导入位于底部以避免循环依赖。

在 handlers.py 模块中,我放弃使用 @app.errorhandler 装饰器将错误处理程序附加到应用程序,而是使用 blueprint 的 @bp.app_errorhandler 装饰器。 尽管两个装饰器最终都达到了相同的结果,但这样做的目的是试图使 blueprint 独立于应用,使其更具可移植性。我还需要修改两个错误模板的路径,因为它们被移动到了新 errors 子目录。

完成错误处理程序重构的最后一步是向应用注册 blueprint:

app/ init .py :向应用注册错误 blueprint。

app = Flask(__name__)

# ...

from app.errors import bp as errors_bp
app.register_blueprint(errors_bp)

# ...

from app import routes, models  # <-- remove errors from this import!

为了注册 blueprint,将使用 Flask 应用实例的 register_blueprint() 方法。 在注册 blueprint 时,任何视图函数,模板,静态文件,错误处理程序等均连接到应用。 我将 blueprint 的导入放在 app.register_blueprint() 的上方,以避免循环依赖。

用户认证 Blueprint

将应用的认证功能重构为 blueprint 的过程与错误处理程序的过程非常相似。 以下是重构为 blueprint 的目录层次结构:

app/
    auth/                               <-- blueprint package
        __init__.py                     <-- blueprint creation
        email.py                        <-- authentication emails
        forms.py                        <-- authentication forms
        routes.py                       <-- authentication routes
    templates/
        auth/                           <-- blueprint templates
            login.html
            register.html
            reset_password_request.html
            reset_password.html
    __init__.py                         <-- blueprint registration

为了创建这个 blueprint,我必须将所有认证相关的功能移到为 blueprint 创建的新模块中。 这包括一些视图函数,Web 表单和支持功能,例如通过电子邮件发送密码重设 token 的功能。 我还将模板移动到一个子目录中,以将它们与应用的其余部分分开,就像我对错误页面所做的那样。

在 blueprint 中定义路由时,使用 @bp.route 装饰器来代替 @app.route 装饰器。 在 url_for() 中用于构建 URL 的语法也需要进行更改。 对于直接附加到应用的常规视图函数, url_for() 的第一个参数是视图函数名称。 但当在 blueprint 中定义路由时,该参数必须包含 blueprint 名称和视图函数名称,并以句点分隔。 因此,我不得不用诸如 url_for('auth.login') 的代码替换所有出现的 url_for('login') 代码,对于其余的视图函数也是如此。

注册 auth blueprint 到应用时,我使用了些许不同的格式:

app/__init__.py :注册用户认证 blueprint 到应用。

# ...
from app.auth import bp as auth_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
# ...

在这种情况下, register_blueprint() 调用接收了一个额外的参数, url_prefix 。 这完全是可选的,Flask 提供了给 blueprint 的路由添加 URL 前缀的选项,因此 blueprint 中定义的任何路由都会在其完整 URL 中获取此前缀。 在许多情况下,这可以用来当成“命名空间”,它可以将 blueprint 中的所有路由与应用或其他 blueprint 中的其他路由分开。 对于用户认证,我认为让所有路由以 /auth 开头很不错,所以我添加了该前缀。 所以现在登录 URL 将会是 http://localhost:5000/auth/login 。 因为我使用 url_for() 来生成 URL,所有 URL 都会自动合并前缀。

主应用 Blueprint

第三个 blueprint 包含核心应用逻辑。 重构这个 blueprint 和前两个 blueprint 的过程一样。 我给这个 blueprint 命名为 main ,因此所有引用视图函数的 url_for() 调用都必须添加一个 main. 前缀。 鉴于这是应用的核心功能,我决定将模板留在原来的位置。 这不会有什么问题,因为我已将其他两个 blueprint 中的模板移动到子目录中了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文