教程:在 Visual Studio 中使用视图和页面模板创建 Flask 应用

本文介绍本教程系列中的步骤 2 在 Visual Studio中使用 Flask Web 框架。

Visual Studio 允许你从项目模板创建 Flask 应用程序,以便为项目提供更广泛的起点。 本教程中的 步骤 1 介绍了如何使用一个页面创建 Flask 应用,其中所有代码都在单个文件中。 在步骤 2 中,重构代码并为页面模板创建一个结构,以实现进一步的开发。 具体而言,需要将应用程序视图的代码与其他方面(如启动代码)分开。

在本教程的步骤 2 中,你将了解如何:

  • 重构应用程序代码以将视图与启动代码分开
  • 使用页面模板呈现视图

先决条件

重构 Flask 项目以供进一步开发

通过“空白 Flask Web 项目”模板,可以创建一个包含单一 app.py 文件的项目,它包含启动代码及单一视图。 若要允许使用多个视图和模板进一步开发应用,需要分隔这些函数。

按照以下步骤调整 Flask 项目,以便进行进一步开发:

  1. 解决方案资源管理器中,右键单击 Flask 项目文件夹(BasicProject),然后选择“添加>新文件夹

    显示如何在 Visual Studio 2022 中添加 Hello Flask 文件夹的屏幕截图。

  2. HelloFlask命名新的应用程序文件夹。

  3. 右键单击 HelloFlask 文件夹,然后选择“添加新项”> 以创建新文件。

  4. 在“添加新项 对话框中,选择 空 Python 文件 文件模板:

    1. 将文件命名为 __init__.py。 文件名应在单词 init 前后包含两个前置下划线和两个后置下划线字符 (_)。

    2. 选择“添加”。

    显示如何在 Visual Studio 2022 中添加 init python 文件的屏幕截图。

  5. 将以下代码添加到新文件,该文件创建 Flask 实例并加载应用程序视图:

    from flask import Flask
    app = Flask(__name__)
    
    import HelloFlask.views
    
  6. HelloFlask 文件夹中,创建另一个名为 views.py的 Python 文件。

    重要

    请务必将文件名指定为 views.py。 由于“__init__.py”文件中的 import HelloFlask.views 语句,名称“views”很重要。 如果两个实例中的名称“views”不同,Visual Studio 会在运行时显示错误。

  7. 将以下代码添加到 views.py 文件。 此代码将重命名函数并定义到 /home 终结点的返回路由:

    from flask import Flask
    from HelloFlask import app
    
    @app.route('/')
    @app.route('/home')
    def home():
        return "Hello Flask!"
    

    此代码还包含 app.py 文件中的页面呈现代码,并导入 __init__.py 文件中声明的 app 对象。

  8. 在 HelloFlask 文件夹中,创建名为“templates”的子文件夹。 文件夹目前为空。

  9. 在 Flask 项目文件夹中(BasicProject),将 app.py 文件的内容替换为以下代码:

    import os
    from HelloFlask import app    # Imports the code from HelloFlask/__init__.py
    
    if __name__ == '__main__':
        HOST = os.environ.get('SERVER_HOST', 'localhost')
    
        try:
            PORT = int(os.environ.get('SERVER_PORT', '5555'))
        except ValueError:
            PORT = 5555
    
        app.run(HOST, PORT)
    
  10. 更新代码后,将 app.py 文件重命名为 runserver.py

  11. 确认重构的 Flask 项目结构如以下示例所示:

    显示 Visual Studio 2022 解决方案资源管理器中更新的 Flask 项目结构的屏幕截图。

    显示 Visual Studio 早期版本中解决方案资源管理器中更新的 Flask 项目结构的屏幕截图。

运行重构的程序并检查路由

现在,你已准备好在 Visual Studio 中运行项目:

  1. 在 Visual Studio 中,选择“调试”>“开始调试”F5),或在主工具栏上选择 Web 服务器(你看到的浏览器可能有所不同):

  2. 当应用程序在浏览器中打开时,请在浏览器中尝试 /(root)和 /home URL 路由终结点:

    屏幕截图显示如何在浏览器中检查重构的 Flask 应用程序的 /home 路径。

在调试器中运行更新的程序

还可以在代码的各个部分设置断点,并在 调试器中遵循应用启动顺序:

  1. 设置多个断点,例如以下几点:

    • runserver.py 文件的第一行
    • __init__.py 文件的第一行
    • “views.py”文件中的 return "Hello Flask!"
  2. 在调试器中通过选择“调试”>“启动调试”或按 F5 启动应用。

  3. 在调试器运行时,使用 F10 单步执行代码,或使用 F5 从每个断点开始运行代码。 还可以在 Visual Studio 的主工具栏上使用调试控件,例如 ContinueStopRestartStep 选项:

    显示 Visual Studio 主工具栏上的调试控件的屏幕截图,例如继续、重启和步骤选项。

  4. 完成后,选择 、Ctrl、、+、、C 和,然后按任意键来停止应用程序。 你还可以关闭与路由相关的任何已打开的浏览器窗口。

将更改提交到源代码管理

重构代码并测试更新后,可以查看并提交对源代码管理所做的更改:

  1. 保存对项目文件的更改,例如使用 Ctrl +S 键盘快捷方式

  2. 在 Git 控件栏上,选择未提交的更改(铅笔 5),打开 Git 更改 窗口:

    显示 Visual Studio 2022 状态栏上未提交的更改选项的屏幕截图。

  3. 在“Git 更改”窗口中,输入提交消息,然后选择“全部提交”:

    屏幕截图,显示如何在“Git 更改”窗口中编辑提交消息并提交重构代码的所有更改。

    提交完成后,Visual Studio 会显示消息“提交<哈希>已在本地创建”

  4. (可选)将提交的更改推送到远程存储库:

    1. 在 Git 控件栏上,选择传出/传入的提交(箭头 1/0)。

    2. 选择“同步”(拉取然后推送)或“推送”。

    显示如何将提交推送到 Visual Studio 2022 中的远程存储库的屏幕截图。

    也可以在将提交推送到远程存储库之前,累积多个本地提交。

  1. 保存对项目文件的更改,例如使用 Ctrl +S 键盘快捷方式

  2. 在 Visual Studio 的右下角选择未提交的更改(铅笔 5),这将打开 团队资源管理器

    显示 Visual Studio 状态栏上的源代码管理更改选项的屏幕截图。

  3. 团队资源管理器中,输入“重构代码”等提交消息,然后选择 提交所有

    提交完成后,Visual Studio 会显示 提交 <哈希> 本地创建的消息。同步以与服务器共享更改。

  4. (可选)将提交的更改推送到远程存储库:

    1. 团队资源管理器中,选择 同步

    2. 展开“传出的提交”,然后选择“推送”。

    屏幕截图,显示如何在团队资源管理器中同步和推送提交到远程存储库。

    也可以在将提交推送到远程存储库之前,累积多个本地提交。

有关本教程系列中的后续过程,请参阅本部分,了解将更改提交到源代码管理的步骤。

确定提交和推送的频率

将更改提交到源代码会在更改日志中创建一个记录以及一个可以将存储库还原到的点(如需)。 还可以检查每个提交以查看特定的更改。

Git 中的提交成本较低。 最好通过频繁的小量提交来提交更改,而不是累积大量更改再一次性提交。

无需对单个文件提交每个小更改。 在添加功能、更改结构(如本教程系列的这一步骤所示)或重构代码时,通常会进行提交。 一个好的做法是与协作者沟通,就最适合每个人的提交粒度达成一致。

提交的频率以及将提交推送到远程存储库的频率是两个不同的问题。 在将提交推送到远程存储库前,可以在本地存储库中积累多个提交。 提交的频率取决于团队希望管理存储库的方式。

使用模板呈现页面和视图

views.py 文件中的 home 函数为页面生成纯文本 HTTP 响应。 大多数实际网页都使用丰富的 HTML 页面做出响应,这些页面通常包含实时数据。 开发人员使用函数定义视图的主要原因是动态生成内容。

视图的返回值只是一个字符串。 您可以通过使用动态内容在字符串中构建任意 HTML。 由于最好将标记与数据分开,因此最好将标记放在模板中并将数据保留在代码中。

调整视图以使用内联 HTML

第一步是转换视图处理,以便对包含一些动态内容的页面使用内联 HTML:

  1. views.py 文件的内容替换为以下代码:

    from datetime import datetime
    from flask import render_template
    from HelloFlask import app
    
    @app.route('/')
    @app.route('/home')
    def home():
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        html_content = "<html><head><title>Hello Flask</title></head><body>"
        html_content += "<strong>Hello Flask!</strong> on " + formatted_now
        html_content += "</body></html>"
    
        return html_content
    
  2. 保存更改并再次运行应用。

  3. 刷新页面几次以确认日期和时间更新。 完成后,停止应用。

创建 HTML 模板

接下来,将页面呈现过程转换为使用 HTML 模板:

  1. 右键单击 文件夹中的 模板,然后选择“添加>新建项 以创建新文件。

  2. 在“添加新项”对话框中,选择“HTML 页面”文件模板。 将文件命名为 index.html 并选择 添加

  3. 将 HTML 文件提供的内容替换为以下标记:

    <html>
    <head>
       <title>Hello Flask</title>
    </head>
    
    <body>
       {{ content }}
    </body>
    </html>
    

    在此代码中,{{ content }} 语句是一个占位符或替换标记(也称为 模板变量),可在其中提供代码中的值。

调整“home”函数以加载模板

需要修改 home 函数以使用 render_template 方法。 此方法加载 HTML 模板,并使用与占位符名称匹配的命名参数为 {{ content }} 提供值。

  1. views.py 文件中,将 home 函数定义替换为以下代码:

    def home():
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        return render_template(
            "index.html",
            content = "<strong>Hello, Flask!</strong> on " + formatted_now)
    

    Flask 自动查找 模板 文件夹中的模板,因此模板的路径相对于该文件夹。

  2. 保存项目更改并再次运行应用。

    请注意,content 值内的内联 HTML 语法 (\<strong> ...) 不呈现为 HTML,因为模板化引擎 (Jinja) 自动转义 HTML 内容。 自动转义可防止意外漏洞注入攻击。

    开发人员通常从一个页面收集输入,并使用模板占位符将其用作另一个页面中的值。 转义还充当提醒:最好将 HTML 保持在代码外。

    完成后,停止应用。

使用不同的占位符

可以对 HTML 标记中的每个数据片段使用不同的占位符。 然后,再次调整 home 函数以提供特定的占位符值:

  1. index.html 文件的内容替换为以下标记:

    <html>
      <head>
        <title>{{ title }}</title>
      </head>
      <body>
        <strong>{{ message }}</strong>{{ content }}
      </body>
    </html>
    
  2. views.py 文件中,将 home 函数定义替换为以下代码,为所有占位符提供值:

    def home():
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        return render_template(
            "index.html",
            title = "Hello Flask",
            message = "Hello, Flask!",
            content = " on " + formatted_now)
    
  3. 保存更改并再次运行应用。 这一次你应该会看到正确呈现的输出。

    显示正在运行的应用程序的屏幕截图,该应用程序使用 HTML 模板呈现页面信息。

  4. 可以将更改提交到源代码管理并更新远程存储库。 有关详细信息,请参阅将更改提交到源代码管理

单独的页面模板

模板通常保留在单独的 HTML 文件中,但也可以使用内联模板。 建议使用单独的文件,以保持标记和代码之间的清晰分离。

对模板使用 .html 扩展

页面模板文件的 .html 扩展名是完全可选的。 始终可以在 render_template 函数的第一个参数中标识文件的确切相对路径。 但是,Visual Studio(和其他编辑器)通常通过 .html 文件提供代码完成和语法着色等功能,这超过了页面模板不是 HTML 的事实。

使用 Flask 项目时,Visual Studio 会自动检测你正在编辑的 HTML 文件是否实际上是 Flask 模板,并提供某些自动完成功能。 如果开始输入 Flask 页面模板注释 ({#),Visual Studio 会自动提供结尾 #} 字符。 注释选择取消注释选择 命令(在 编辑>高级 菜单上)也使用模板注释,而不是 HTML 注释。

将模板组织到子文件夹中

可以使用子文件夹,然后在 模板下引用 文件夹下的相对路径,以调用 render_template 函数。 此方法是有效地为模板创建命名空间的好方法。

下一步