现已发布!阅读关于 11 月新增功能和修复的内容。

Visual Studio Code 中的 Flask 教程

Flask 是一个轻量级的 Python Web 应用框架,它提供了 URL 路由和页面渲染的基础功能。

Flask 被称为“微框架”,因为它不直接提供表单验证、数据库抽象、身份验证等功能。这些功能由称为 Flask 扩展的特殊 Python 包提供。这些扩展与 Flask 无缝集成,看起来就像 Flask 本身的一部分。例如,Flask 不提供页面模板引擎,但安装 Flask 会默认包含 Jinja 模板引擎。为了方便起见,我们通常将这些默认设置视为 Flask 的一部分。

在本 Flask 教程中,你将创建一个简单的 Flask 应用,其中包含三个页面,它们使用一个通用的基本模板。在此过程中,你将体验 Visual Studio Code 的多项功能,包括使用终端、编辑器、调试器、代码片段等。

本 Flask 教程的完整代码项目可在 GitHub 上找到:python-sample-vscode-flask-tutorial

如果你有任何问题,可以在 Python 扩展讨论问答中搜索答案或提问。

先决条件

要成功完成本 Flask 教程,你需要执行以下操作(这些步骤与通用 Python 教程中的步骤相同):

  1. 安装 Python 扩展

  2. 安装 Python 3 的某个版本(本教程基于此版本编写)。选项包括:

    • (所有操作系统)从python.org下载;通常使用页面上出现的第一个“下载”按钮。
    • (Linux)内置的 Python 3 安装效果很好,但要安装其他 Python 包,您必须在终端中运行 sudo apt install python3-pip
    • (macOS)在 macOS 上通过Homebrew安装,使用命令 `brew install python3`。
    • (所有操作系统)从 Anaconda 下载(用于数据科学目的)。
  3. 在 Windows 上,请确保您的 Python 解释器位置已包含在 PATH 环境变量中。您可以在命令提示符下运行 path 来检查该位置。如果 Python 解释器的文件夹未包含在内,请打开 Windows 设置,搜索“环境”,选择为您的帐户编辑环境变量,然后编辑 Path 变量以包含该文件夹。

为 Flask 教程创建项目环境

在本节中,你将创建一个安装了 Flask 的虚拟环境。使用虚拟环境可以避免将 Flask 安装到全局 Python 环境中,并让你精确控制应用程序中使用的库。

  1. 在文件系统中,为本教程创建一个文件夹,例如 `hello_flask`。

  2. 在终端中导航到该文件夹,然后运行 `code .` 来在 VS Code 中打开该文件夹,或者运行 VS Code 并使用“文件” > “打开文件夹”命令。

  3. 在 VS Code 中,打开命令面板(“视图” > “命令面板”或(⇧⌘P (Windows、Linux Ctrl+Shift+P)))。然后选择“Python: Create Environment”命令来在你的工作区创建虚拟环境。选择 `venv`,然后选择要用于创建它的 Python 环境。

    注意:如果你想手动创建环境,或者在环境创建过程中遇到错误,请访问“环境”页面。

    Flask tutorial: opening the Command Palette in VS Code

  4. 在虚拟环境创建完成后,从命令面板运行“终端: 创建新终端”(⌃⇧` (Windows、Linux Ctrl+Shift+`)),这会创建一个终端并自动激活虚拟环境(通过运行其激活脚本)。

    注意:在 Windows 上,如果您的默认终端类型是 PowerShell,您可能会看到一个错误,提示无法运行 activate.ps1,因为系统禁用了脚本运行。该错误提供了一个链接,说明如何允许脚本运行。或者,使用终端:选择默认配置文件将“命令提示符”或“Git Bash”设置为您的默认终端。

  5. 通过在 VS Code 终端中运行以下命令,在虚拟环境中安装 Flask:

    python -m pip install flask
    

现在你拥有了一个用于编写 Flask 代码的独立环境。当你使用“终端: 创建新终端”时,VS Code 会自动激活该环境。如果你打开一个单独的命令提示符或终端,请通过运行 `source .venv/bin/activate`(Linux/macOS)或 `.venv\Scripts\Activate.ps1`(Windows)来激活环境。当命令提示符开头显示 **(.venv)** 时,表示环境已激活。

创建并运行一个最小化的 Flask 应用

  1. 在 VS Code 中,使用“文件” > “新建”菜单、按 Ctrl+N 键,或使用资源管理器视图中的新建文件图标(如下所示),在项目文件夹中创建一个名为 `app.py` 的新文件。

    Flask tutorial: new file icon in Explorer View

  2. 在 `app.py` 中,添加代码以导入 Flask 并创建一个 Flask 对象实例。如果你手动输入代码(而不是复制粘贴),你将能够看到 VS Code 的 IntelliSense 和自动补全功能。

    from flask import Flask
    app = Flask(__name__)
    
  3. 同样在 `app.py` 中,添加一个返回内容的函数(在本例中为简单字符串),并使用 Flask 的 `app.route` 装饰器将 URL 路由 `/` 映射到该函数。

    @app.route("/")
    def home():
        return "Hello, Flask!"
    

    提示:你可以为同一个函数使用多个装饰器,每个装饰器占一行,具体取决于你想将多少不同的路由映射到同一个函数。

  4. 保存 `app.py` 文件(⌘S (Windows、Linux Ctrl+S))。

  5. 在集成终端中,通过输入 `python -m flask run` 来运行应用,这将启动 Flask 开发服务器。开发服务器默认查找 `app.py`。运行 Flask 时,你应该会看到类似以下的输出:

    (.venv) D:\py\\hello_flask>python -m flask run
     * Environment: production
       WARNING: Do not use the development server in a production environment.
       Use a production WSGI server instead.
     * Debug mode: off
     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    

    如果你看到“找不到 Flask 模块”的错误,请确保你在虚拟环境中运行了 `python -m pip install flask`,如上一节末尾所述。

    另外,如果你想在不同的 IP 地址或端口上运行开发服务器,请使用 `host` 和 `port` 命令行参数,例如 ` --host=0.0.0.0 --port=80`。

  6. 要打开默认浏览器并查看渲染的页面,请在终端中按 Ctrl+click 单击 `http://127.0.0.1:5000/` URL。

    Flask tutorial: the running app in a browser

  7. 请注意,当你访问如 `/` 这样的 URL 时,调试终端会显示 HTTP 请求的消息。

    127.0.0.1 - - [11/Jul/2018 08:40:15] "GET / HTTP/1.1" 200 -
    
  8. 在终端中使用 Ctrl+C 停止应用。

提示:如果你使用的文件名不是 `app.py`,而是例如 `webapp.py`,则需要定义一个名为 `FLASK_APP` 的环境变量,并将其值设置为你选择的文件。Flask 的开发服务器将使用 `FLASK_APP` 的值而不是默认文件 `app.py`。有关更多信息,请参阅 Flask 命令行界面

在调试器中运行应用

调试让您有机会在特定代码行暂停正在运行的程序。当程序暂停时,您可以检查变量,在“调试控制台”面板中运行代码,以及利用调试页面上描述的其他功能。运行调试器还会在调试会话开始前自动保存任何已修改的文件。

开始之前:请确保您已在上一节末尾通过在终端中使用 Ctrl+C 停止了正在运行的应用。如果您在一个终端中让应用保持运行,它会继续占用该端口。结果是,当您使用相同的端口在调试器中运行应用时,原始运行的应用会处理所有请求,您将不会在被调试的应用中看到任何活动,并且程序不会在断点处停止。换句话说,如果调试器似乎不起作用,请确保没有其他应用实例仍在运行。

  1. 将 `app.py` 的内容替换为以下代码,该代码添加了一个第二个路由和函数,你可以在调试器中单步执行:

    import re
    from datetime import datetime
    
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def home():
        return "Hello, Flask!"
    
    
    @app.route("/hello/<name>")
    def hello_there(name):
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        # Filter the name argument to letters only using regular expressions. URL arguments
        # can contain arbitrary text, so we restrict to safe characters only.
        match_object = re.match("[a-zA-Z]+", name)
    
        if match_object:
            clean_name = match_object.group(0)
        else:
            clean_name = "Friend"
    
        content = "Hello there, " + clean_name + "! It's " + formatted_now
        return content
    

    为新 URL 路由 `/hello/` 使用的装饰器定义了一个端点 `/hello/`,该端点可以接受任何附加值。路由中 `<` 和 `>` 内的标识符定义了一个变量,该变量将传递给函数并在你的代码中使用。

    URL 路由区分大小写。例如,路由 `/hello/` 与 `/Hello/` 不同。如果你希望同一个函数处理两者,请为每个变体使用装饰器。

    如代码注释中所述,始终过滤任意用户提供的信息以避免对你的应用进行各种攻击。在本例中,代码会过滤 `name` 参数,使其只包含字母,从而避免注入控制字符、HTML 等。(当你使用下一节中的模板时,Flask 会进行自动过滤,你将不需要这段代码。)

  2. hello_there 函数的第一行代码 (now = datetime.now()) 处设置一个断点,方法如下任选其一:

    • 将光标放在该行上,按 F9,或者,
    • 将光标放在该行上,选择运行 > 切换断点菜单命令,或者,
    • 直接点击行号左侧的空白处(当鼠标悬停在那里时会出现一个褪色的红点)。

    断点在左边距显示为一个红点:

    Flask tutorial: a breakpoint set on the first line of the hello_there function

  3. 切换到 VS Code 中的“运行和调试”视图(使用左侧活动栏或 ⇧⌘D (Windows、Linux Ctrl+Shift+D))。你可能会看到消息“To customize Run and Debug create a launch.json file”。这意味着你还没有包含调试配置的 `launch.json` 文件。如果你点击“创建 launch.json 文件”链接,VS Code 可以为你创建它。

    Flask tutorial: initial view of the debug panel

  4. 选择该链接,VS Code 将提示你进行调试配置。从下拉列表中选择 **Flask**,VS Code 将用 Flask 运行配置填充一个新的 `launch.json` 文件。`launch.json` 文件包含多个调试配置,每个配置都是 `configuration` 数组中的一个独立 JSON 对象。

  5. 向下滚动并检查名为“Python: Flask”的配置。此配置包含 `"module": "flask",`,它告诉 VS Code 在启动调试器时使用 `-m flask` 运行 Python。它还通过 `env` 属性定义了 `FLASK_APP` 环境变量,以识别启动文件(默认是 `app.py`),但允许你轻松指定其他文件。如果你想更改主机和/或端口,可以使用 `args` 数组。

    {
        "name": "Python Debugger: Flask",
        "type": "debugpy",
        "request": "launch",
        "module": "flask",
        "env": {
            "FLASK_APP": "app.py",
            "FLASK_DEBUG": "1"
        },
        "args": [
            "run",
            "--no-debugger",
            "--no-reload"
        ],
        "jinja": true,
        "justMyCode": true
    },
    

    注意:如果你的配置中的 `env` 条目包含 `"FLASK_APP": "${workspaceFolder}/app.py"`,请将其更改为 `"FLASK_APP": "app.py"`,如上所示。否则,你可能会遇到类似“无法导入模块 C”的错误消息,其中 C 是项目文件夹所在驱动器的盘符。

    注意:一旦创建了 `launch.json` 文件,编辑器中就会出现一个“添加配置”按钮。该按钮会显示一个附加配置列表,将它们添加到配置列表的开头。(“运行”>“添加配置”菜单命令执行相同的操作。)

  6. 保存 `launch.json`(⌘S (Windows、Linux Ctrl+S))。在调试配置下拉列表中,选择 **Python: Flask** 配置。

    Flask tutorial: selecting the Flask debugging configuration

  7. 通过选择运行 > 启动调试菜单命令,或选择列表旁边的绿色启动调试箭头 (F5) 来启动调试器:

    Flask tutorial: start debugging/continue arrow on the debug toolbar

    观察状态栏颜色变化,表示正在调试:

    Flask tutorial: appearance of the debugging status bar

    VS Code 中还会出现一个调试工具栏(如下所示),其中包含按顺序排列的命令:暂停(或继续,F5)、逐过程(F10)、逐语句(F11)、跳出(⇧F11 (Windows、Linux Shift+F11))、重启(⇧⌘F5 (Windows、Linux Ctrl+Shift+F5))和停止(⇧F5 (Windows、Linux Shift+F5))。请参阅 VS Code 调试以了解每个命令的说明。

    Flask tutorial: the VS Code debug toolbar

  8. 输出显示在“Python 调试控制台”终端中。按 Ctrl+click 单击该终端中的 `http://127.0.0.1:5000/` 链接,在浏览器中打开该 URL。在浏览器的地址栏中,导航到 `http://127.0.0.1:5000/hello/VSCode`。在页面渲染之前,VS Code 会在设置的断点处暂停程序。断点上的小黄箭头表示下一行要执行的代码。

    Flask tutorial: VS Code paused at a breakpoint

  9. 使用“单步跳过”来运行 now = datetime.now() 语句。

  10. 在 VS Code 窗口的左侧,您会看到一个变量窗格,其中显示了局部变量(如 now)以及参数(如 name)。其下方是监视调用堆栈断点窗格(详见VS Code 调试)。在局部变量部分,尝试展开不同的值。您还可以双击值(或使用 Enter (Windows, Linux F2))来修改它们。然而,更改像 now 这样的变量可能会破坏程序。开发人员通常只在代码最初没有产生正确值时才进行更改以纠正值。

    Flask tutorial: local variables and arguments in VS Code during debugging

  11. 当程序暂停时,“调试控制台”面板(与终端面板中的“Python 调试控制台”不同)允许你通过当前程序状态尝试表达式和代码片段。例如,在单步执行完 `now = datetime.now()` 这一行之后,你可能想尝试不同的日期/时间格式。在编辑器中,选择读取 `now.strftime("%A, %d %B, %Y at %X")` 的代码,然后右键单击并选择“在调试控制台中求值”,将该代码发送到调试控制台并运行。

    now.strftime("%A, %d %B, %Y at %X")
    'Wednesday, 31 October, 2018 at 18:13:39'
    

    提示调试控制台还会显示应用内部的异常,这些异常可能不会出现在终端中。例如,如果您在运行和调试视图的调用堆栈区域看到“在异常处暂停”的消息,请切换到调试控制台查看异常消息。

  12. 将该行复制到调试控制台底部的 > 提示符处,并尝试更改格式:

    now.strftime("%a, %d %B, %Y at %X")
    'Wed, 31 October, 2018 at 18:13:39'
    now.strftime("%a, %d %b, %Y at %X")
    'Wed, 31 Oct, 2018 at 18:13:39'
    now.strftime("%a, %d %b, %y at %X")
    'Wed, 31 Oct, 18 at 18:13:39'
    
  13. 如果您愿意,可以再单步执行几行代码,然后选择“继续”(F5) 让程序运行。浏览器窗口将显示结果:

    Flask tutorial: result of the modified program

  14. 将代码中的行更改为使用不同的日期时间格式,例如 `now.strftime("%a, %d %b, %y at %X")`,然后保存文件。Flask 服务器将自动重新加载,这意味着更改将在无需重新启动调试器的情况下生效。在浏览器中刷新页面以查看更新。

  15. 完成后,关闭浏览器并停止调试器。要停止调试器,请使用停止工具栏按钮(红色方块)或运行 > 停止调试命令 (⇧F5 (Windows, Linux Shift+F5))。

提示:为了方便反复导航到特定 URL,例如 `http://127.0.0.1:5000/hello/VSCode`,请通过 `print` 语句输出该 URL。URL 会出现在终端中,你可以使用 Ctrl+click 在浏览器中打开它。

“转到定义”和“速览定义”命令

在使用 Flask 或任何其他库进行工作时,你可能想检查这些库本身的代码。VS Code 提供了两个方便的命令,可以直接导航到任何代码中类和其他对象的定义。

  • **转到定义**可以从你的代码跳转到定义对象的代码。例如,在 `app.py` 中,右键单击 `Flask` 类(在 `app = Flask(__name__)` 行中)并选择“转到定义”(或使用 F12),这将导航到 Flask 库中的类定义。

  • 速览定义 (⌥F12 (Windows Alt+F12, Linux Ctrl+Shift+F10),也在右键上下文菜单中),功能类似,但直接在编辑器中显示类定义(在编辑器窗口中腾出空间以避免遮挡任何代码)。按 Escape 关闭速览窗口,或使用右上角的 x

    Flask tutorial: peek definition showing the Flask class inline

使用模板渲染页面

到目前为止,本教程中创建的应用仅从 Python 代码生成纯文本网页。虽然可以直接在代码中生成 HTML,但开发者避免这种做法,因为它会导致应用容易受到跨站脚本 (XSS) 攻击。例如,在本教程的 `hello_there` 函数中,你可能会认为在代码中使用类似 `content = "<h1>Hello there, " + clean_name + "!</h1>"` 的方式来格式化输出,其中 `content` 的结果直接提供给浏览器。这种方式允许攻击者在 URL 中插入恶意 HTML(包括 JavaScript 代码),这些代码最终会进入 `clean_name`,并在浏览器中执行。

一个更好的做法是完全将 HTML 排除在代码之外,通过使用模板,这样您的代码只关心数据值,而不关心渲染。

  • 模板是一个 HTML 文件,其中包含代码在运行时提供的值的占位符。模板引擎负责在渲染页面时进行替换。因此,代码只关注数据值,模板只关注标记。
  • Flask 的默认模板引擎是 Jinja,它在安装 Flask 时会自动安装。该引擎提供了灵活的选项,包括自动转义(防止 XSS 攻击)和模板继承。通过继承,你可以定义一个包含通用标记的基础页面,然后基于该基础页面构建特定于页面的添加内容。

在本节中,你将创建一个使用模板的单个页面。在接下来的几节中,你将配置应用来提供静态文件,然后为应用创建多个页面,每个页面都包含一个来自基础模板的导航栏。

  1. 在 `hello_flask` 文件夹内,创建一个名为 `templates` 的文件夹,Flask 默认在此文件夹中查找模板。

  2. 在 `templates` 文件夹中,创建一个名为 `hello_there.html` 的文件,其内容如下。此模板包含两个名为“name”和“date”的占位符,它们由一对花括号 `{{` 和 `}}` 分隔。如你所见,你也可以直接在模板中包含格式化代码。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>Hello, Flask</title>
        </head>
        <body>
            {%if name %}
                <strong>Hello there, {{ name }}!</strong> It's {{ date.strftime("%A, %d %B, %Y at %X") }}.
            {% else %}
                What's your name? Provide it after /hello/ in the URL.
            {% endif %}
        </body>
    </html>
    

    提示:Flask 开发者通常使用 flask-babel 扩展进行日期格式化,而不是 `strftime`,因为 flask-babel 会考虑区域设置和时区。

  3. 在 `app.py` 中,在文件顶部附近导入 Flask 的 `render_template` 函数。

    from flask import render_template
    
  4. 同样在 `app.py` 中,修改 `hello_there` 函数以使用 `render_template` 来加载模板并应用命名值(并添加一个路由以识别没有名字的情况)。`render_template` 假定第一个参数相对于 `templates` 文件夹。通常,开发者将模板命名为与使用它们的函数相同,但名称匹配并非必需,因为你在代码中始终引用确切的文件名。

    @app.route("/hello/")
    @app.route("/hello/<name>")
    def hello_there(name = None):
        return render_template(
            "hello_there.html",
            name=name,
            date=datetime.now()
        )
    

    您可以看到代码现在变得简单得多,只关心数据值,因为标记和格式化都包含在模板中。

  5. 启动程序(在调试器内部或外部,使用 ⌃F5 (Windows, Linux Ctrl+F5)),导航到 /hello/name URL,并观察结果。

  6. 尝试导航到 `/hello/name` URL,使用一个像 `<a%20value%20that%20could%20be%20HTML>` 这样的名字,以查看 Flask 的自动转义功能。在浏览器中,“name”值将显示为纯文本,而不是渲染为实际元素。

提供静态文件

静态文件有两种类型。第一种是样式表等文件,页面模板可以直接引用。这些文件可以放在应用中的任何文件夹中,但通常放在 `static` 文件夹内。

第二种是你想在代码中引用的文件,例如当你想要实现一个返回静态文件的 API 端点时。为此,Flask 对象包含一个内置方法 `send_static_file`,它生成一个包含应用 `static` 文件夹中的静态文件的响应。

以下各节将演示这两种类型的静态文件。

在模板中引用静态文件

  1. 在 `hello_flask` 文件夹中,创建一个名为 `static` 的文件夹。

  2. 在 `static` 文件夹中,创建一个名为 `site.css` 的文件,其内容如下。输入此代码后,还可以观察 VS Code 为 CSS 文件提供的语法高亮显示,包括颜色预览。

    .message {
        font-weight: 600;
        color: blue;
    }
    
  3. 在 `templates/hello_there.html` 中,在 `` 标签之前添加以下行,它创建了一个对样式表的引用。

    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='site.css')}}" />
    

    这里使用的 Flask url_for 标签会创建文件的正确路径。由于它可以接受变量作为参数,因此 `url_for` 允许你按需以编程方式控制生成的路径。

  4. 同样在 `templates/hello_there.html` 中,将 `` 元素的内容替换为以下标记,该标记使用 `message` 样式而不是 `` 标签(并且当你仅使用不带名字的 hello/ URL 时也会显示消息)。

    {%if name %}
        <span class="message">Hello there, {{ name }}!</span> It's {{ date.strftime("%A, %d %B, %Y at %X") }}.
    {% else %}
        <span class="message">What's your name? Provide it after /hello/ in the URL.</span>
    {% endif %}
    
  5. 运行应用,导航到 /hello/name URL,并观察到消息以蓝色呈现。完成后停止应用。

从代码中提供静态文件

  1. 在 `static` 文件夹中,创建一个名为 `data.json` 的 JSON 数据文件,其内容如下(这是无意义的示例数据)。

    {
      "01": {
        "note": "This data is very simple because we're demonstrating only the mechanism."
      }
    }
    
  2. 在 `app.py` 中,添加一个带有 `/api/data` 路由的函数,该函数使用 `send_static_file` 方法返回静态数据文件。

    @app.route("/api/data")
    def get_data():
        return app.send_static_file("data.json")
    
  3. 运行应用并导航到 `/api/data` 端点,以查看静态文件是否已返回。完成后停止应用。

创建多个继承自基础模板的模板

由于大多数 Web 应用都有多个页面,并且这些页面通常共享许多公共元素,因此开发者会将这些公共元素分离到一个基础页面模板中,然后其他页面模板可以扩展(这也称为模板继承)。

此外,由于您可能会创建许多继承自同一模板的页面,因此在 VS Code 中创建一个代码片段会很有帮助,您可以用它来快速初始化新的页面模板。代码片段从单一来源提供一致的代码块,从而避免了在使用复制粘贴现有代码时可能出现的错误。

以下各节将逐步介绍此过程的不同部分。

创建基础页面模板和样式

Flask 中的基础页面模板包含一组页面的所有共享部分,包括对 CSS 文件、脚本文件等的引用。基础模板还定义了一个或多个 **block** 标签,继承基础的其他模板应该覆盖这些标签。块标签在基础模板和扩展模板中都用 `{% block %}` 和 `{% endblock %}` 分隔。

以下步骤演示了如何创建基础模板。

  1. 在 `templates` 文件夹中,创建一个名为 `layout.html` 的文件,其内容如下,它包含名为“title”和“content”的块。如你所见,标记定义了一个简单的导航栏结构,其中包含指向主页、关于页和联系页面的链接,你将在后续部分创建这些页面。每个链接再次使用 Flask 的 `url_for` 标签在运行时生成匹配路由的链接。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>{% block title %}{% endblock %}</title>
            <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='site.css')}}" />
        </head>
    
        <body>
            <div class="navbar">
                <a href="{{ url_for('home') }}" class="navbar-brand">Home</a>
                <a href="{{ url_for('about') }}" class="navbar-item">About</a>
                <a href="{{ url_for('contact') }}" class="navbar-item">Contact</a>
            </div>
    
            <div class="body-content">
                {% block content %}
                {% endblock %}
                <hr/>
                <footer>
                    <p>&copy; 2018</p>
                </footer>
            </div>
        </body>
    </html>
    
  2. 将以下样式添加到 `static/site.css` 中,放在现有的“message”样式下方,并保存文件。请注意,本演练并未尝试演示响应式设计;这些样式仅生成一个合理有趣的结果。

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    

此时您可以运行应用,但由于您没有在任何地方使用基础模板,也没有更改任何代码文件,结果与上一步相同。完成其余部分以查看最终效果。

创建代码片段

由于您在下一节中创建的三个页面都继承自 layout.html,因此创建一个代码片段来初始化一个带有对基础模板正确引用的新模板文件可以节省时间。代码片段从单一来源提供一致的代码,避免了在使用复制粘贴现有代码时可能出现的错误。

  1. 在 VS Code 中,选择“文件” > “首选项” > **“配置代码片段”**。

  2. 在出现的列表中,选择 **html**。如果你之前创建过代码片段,该选项可能会在列表的“现有代码片段”部分显示为“html.json”。

  3. 在 VS Code 打开 `html.json` 后,在现有花括号内添加以下条目(此处未显示的解释性注释描述了诸如 `$0` 行指示 VS Code 在插入代码片段后将光标放在何处等详细信息)。

    "Flask Tutorial: template extending layout.html": {
        "prefix": "flextlayout",
        "body": [
            "{% extends \"layout.html\" %}",
            "{% block title %}",
            "$0",
            "{% endblock %}",
            "{% block content %}",
            "{% endblock %}"
        ],
    
        "description": "Boilerplate template that extends layout.html"
    },
    
  4. 保存 html.json 文件 (⌘S (Windows, Linux Ctrl+S))。

  5. 现在,每当你开始键入代码片段的触发器(如 `flext`)时,VS Code 都会将该代码片段作为自动完成选项提供,如下一节所示。你还可以使用“插入代码片段”命令从菜单中选择一个代码片段。

有关代码片段的更多信息,请参阅创建代码片段

使用代码片段添加页面

有了代码片段,您可以快速为主页、关于和联系页面创建模板。

  1. 在 `templates` 文件夹中,创建一个名为 `home.html` 的新文件。然后开始输入 `flext`,你将看到代码片段作为完成选项出现。

    Flask tutorial: autocompletion for the flextlayout code snippet

    当您选择该补全项时,代码片段的代码会出现,光标位于代码片段的插入点:

    Flask tutorial: insertion of the flextlayout code snippet

  2. 在“title”块的插入点,输入 `Home`,在“content”块中输入 `

    Home page for the Visual Studio Code Flask tutorial.

    `,然后保存文件。这些行是扩展页面模板的唯一唯一部分。

  3. 在 `templates` 文件夹中,创建 `about.html`,使用代码片段插入样板标记,在“title”和“content”块中分别插入 `About us` 和 `

    About page for the Visual Studio Code Flask tutorial.

    `,然后保存文件。

  4. 重复上一步,使用 `Contact us` 和 `

    Contact page for the Visual Studio Code Flask tutorial.

    ` 在两个内容块中创建 `templates/contact.html`。

  5. 在 `app.py` 中,添加 `/about/` 和 `/contact/` 路由的函数,这些函数引用各自的页面模板。同时修改 `home` 函数以使用 `home.html` 模板。

    # Replace the existing home function with the one below
    @app.route("/")
    def home():
        return render_template("home.html")
    
    # New functions
    @app.route("/about/")
    def about():
        return render_template("about.html")
    
    @app.route("/contact/")
    def contact():
        return render_template("contact.html")
    

运行应用

在所有页面模板就位后,保存 `app.py`,运行应用,然后在浏览器中查看结果。在页面之间导航以验证页面模板是否正确扩展了基础模板。

Flask tutorial: app rendering a common nav bar from the base template

注意:如果你没有看到最新的更改,可能需要对页面进行硬刷新以避免看到缓存文件。

可选活动

以下各节描述了在您使用 Python 和 Visual Studio Code 时可能会有帮助的其他步骤。

为环境创建一个 requirements.txt 文件

当你通过源代码管理或其他方式共享你的应用代码时,复制虚拟环境中的所有文件是没有意义的,因为接收者总是可以自己重新创建环境。

因此,开发人员通常会从源代码控制中省略虚拟环境文件夹,而是使用 requirements.txt 文件来描述应用的依赖项。

虽然您可以手动创建该文件,但也可以使用 pip freeze 命令根据已激活环境中安装的确切库来生成文件:

  1. 使用 Python: Select Interpreter 命令选择您想要的环境后,运行 Terminal: Create New Terminal 命令 (⌃⇧` (Windows, Linux Ctrl+Shift+`))) 打开一个激活了该环境的终端。

  2. 在终端中,运行 pip freeze > requirements.txt 在您的项目文件夹中创建 requirements.txt 文件。

任何接收项目副本的人(或任何构建服务器)只需要运行 `pip install -r requirements.txt` 命令即可重新安装原始环境中的包。(但接收者仍需要创建自己的虚拟环境。)

注意pip freeze 会列出您在当前环境中安装的所有 Python 包,包括您当前未使用的包。该命令还会列出带有确切版本号的包,您可能希望将其转换为范围以便将来更具灵活性。更多信息,请参阅 pip 命令文档中的需求文件

重构项目以支持进一步开发

在本 Flask 教程中,所有应用代码都包含在一个 `app.py` 文件中。为了允许进一步开发和分离关注点,将 `app.py` 的各个部分重构到单独的文件中会很有帮助。

  1. 在你的项目文件夹中,创建一个用于应用的文件夹,例如 `hello_app`,以将它的文件与 `requirements.txt` 和 VS Code 存储设置及调试配置文件的 `.vscode` 文件夹等项目级别文件分开。

  2. 将 `static` 和 `templates` 文件夹移到 `hello_app` 中,因为这些文件夹肯定包含应用代码。

  3. 在 `hello_app` 文件夹中,创建一个名为 `views.py` 的文件,其中包含路由和视图函数。

    from flask import Flask
    from flask import render_template
    from datetime import datetime
    from . import app
    
    @app.route("/")
    def home():
        return render_template("home.html")
    
    @app.route("/about/")
    def about():
        return render_template("about.html")
    
    @app.route("/contact/")
    def contact():
        return render_template("contact.html")
    
    @app.route("/hello/")
    @app.route("/hello/<name>")
    def hello_there(name = None):
        return render_template(
            "hello_there.html",
            name=name,
            date=datetime.now()
        )
    
    @app.route("/api/data")
    def get_data():
        return app.send_static_file("data.json")
    
  4. 在 `hello_app` 文件夹中,创建一个名为 `__init__.py` 的文件,内容如下:

    import flask
    app = flask.Flask(__name__)
    
  5. 在 `hello_app` 文件夹中,创建一个名为 `webapp.py` 的文件,内容如下:

    # Entry point for the application.
    from . import app    # For application discovery by the 'flask' command.
    from . import views  # For import side-effects of setting up routes.
    
  6. 打开调试配置文件 `launch.json`,并将 `env` 属性更新为以下内容,以指向启动对象:

    "env": {
        "FLASK_APP": "hello_app.webapp"
    },
    
  7. 删除项目根目录下的原始 `app.py` 文件,因为其内容已移至其他应用文件中。

  8. 你的项目结构现在应该类似如下:

    Flask tutorial: modified project structure with separate files and folders for parts of the app

  9. 再次在调试器中运行应用,以确保一切正常。要 VS Code 调试器外部运行应用,请在终端中使用以下步骤:

    1. 设置 `FLASK_APP` 的环境变量。在 Linux 和 macOS 上,使用 `export set FLASK_APP=webapp`;在 Windows 上,如果你使用 PowerShell,则使用 `$env:FLASK_APP=webapp`,或者如果你使用命令提示符,则使用 `set FLASK_APP=webapp`。
    2. 导航到 `hello_app` 文件夹,然后使用 `python -m flask run` 启动程序。

使用 Container Tools 扩展为 Flask 应用创建容器

用于容器工具的扩展可以轻松地从 Visual Studio Code 构建、管理和部署容器化应用程序。如果你有兴趣了解如何为本教程开发的 Flask 应用创建 Python 容器,请查看容器中的 Python教程,该教程将引导你完成以下步骤:

  • 创建一个描述简单 Python 容器的 Dockerfile 文件。
  • 构建、运行并验证 Flask 应用的功能。
  • 调试在容器中运行的应用程序。

如果你有任何问题,可以在 Python 扩展讨论问答中搜索答案或提问。

后续步骤

恭喜你完成了本 Visual Studio Code 中 Flask 工作流程的讲解!

本教程的完整代码项目可在 GitHub 上找到:python-sample-vscode-flask-tutorial

由于本教程仅触及了页面模板的表面,有关模板的更多信息,请参阅 Jinja2 文档。模板设计者文档包含了模板语言的所有详细信息。你可能还想回顾一下官方 Flask 教程以及 Flask扩展的文档。

要在生产网站上试用您的应用,请查看教程使用 Docker 容器将 Python 应用部署到 Azure 应用服务。Azure 还提供了一个标准容器,即Linux 上的应用服务,您可以从 VS Code 中将 Web 应用部署到该服务。

您可能还想查看 VS Code 文档中与 Python 相关的以下文章:

© . This site is unofficial and not affiliated with Microsoft.