本文介绍本教程系列中的步骤 2 在 Visual Studio中使用 Flask Web 框架。
Visual Studio 允许你从项目模板创建 Flask 应用程序,以便为项目提供更广泛的起点。 本教程中的 步骤 1 介绍了如何使用一个页面创建 Flask 应用,其中所有代码都在单个文件中。 在步骤 2 中,重构代码并为页面模板创建一个结构,以实现进一步的开发。 具体而言,需要将应用程序视图的代码与其他方面(如启动代码)分开。
在本教程的步骤 2 中,你将了解如何:
- 重构应用程序代码以将视图与启动代码分开
- 使用页面模板呈现视图
先决条件
重构 Flask 项目以供进一步开发
通过“空白 Flask Web 项目”模板,可以创建一个包含单一 app.py 文件的项目,它包含启动代码及单一视图。 若要允许使用多个视图和模板进一步开发应用,需要分隔这些函数。
按照以下步骤调整 Flask 项目,以便进行进一步开发:
在 解决方案资源管理器中,右键单击 Flask 项目文件夹(BasicProject),然后选择“添加>新文件夹。
HelloFlask命名新的应用程序文件夹。
右键单击 HelloFlask 文件夹,然后选择“添加新项”> 以创建新文件。
在“添加新项 对话框中,选择 空 Python 文件 文件模板:
将文件命名为 __init__.py。 文件名应在单词 init 前后包含两个前置下划线和两个后置下划线字符 (
_
)。选择“添加”。
将以下代码添加到新文件,该文件创建
Flask
实例并加载应用程序视图:from flask import Flask app = Flask(__name__) import HelloFlask.views
在 HelloFlask 文件夹中,创建另一个名为 views.py的 Python 文件。
重要
请务必将文件名指定为 views.py。 由于“__init__.py”文件中的
import HelloFlask.views
语句,名称“views”很重要。 如果两个实例中的名称“views”不同,Visual Studio 会在运行时显示错误。将以下代码添加到 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
对象。在 HelloFlask 文件夹中,创建名为“templates”的子文件夹。 文件夹目前为空。
在 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)
更新代码后,将 app.py 文件重命名为 runserver.py。
确认重构的 Flask 项目结构如以下示例所示:
运行重构的程序并检查路由
现在,你已准备好在 Visual Studio 中运行项目:
在 Visual Studio 中,选择“调试”>“开始调试”(F5),或在主工具栏上选择 Web 服务器(你看到的浏览器可能有所不同):
当应用程序在浏览器中打开时,请在浏览器中尝试
/
(root)和/home
URL 路由终结点:
在调试器中运行更新的程序
还可以在代码的各个部分设置断点,并在 调试器中遵循应用启动顺序:
设置多个断点,例如以下几点:
- runserver.py 文件的第一行
- __init__.py 文件的第一行
- “views.py”文件中的
return "Hello Flask!"
行
在调试器中通过选择“调试”>“启动调试”或按 F5 启动应用。
在调试器运行时,使用 F10 单步执行代码,或使用 F5 从每个断点开始运行代码。 还可以在 Visual Studio 的主工具栏上使用调试控件,例如 Continue、Stop、Restart和 Step 选项:
完成后,选择 、Ctrl、、+、、C 和,然后按任意键来停止应用程序。 你还可以关闭与路由相关的任何已打开的浏览器窗口。
将更改提交到源代码管理
重构代码并测试更新后,可以查看并提交对源代码管理所做的更改:
有关本教程系列中的后续过程,请参阅本部分,了解将更改提交到源代码管理的步骤。
确定提交和推送的频率
将更改提交到源代码会在更改日志中创建一个记录以及一个可以将存储库还原到的点(如需)。 还可以检查每个提交以查看特定的更改。
Git 中的提交成本较低。 最好通过频繁的小量提交来提交更改,而不是累积大量更改再一次性提交。
无需对单个文件提交每个小更改。 在添加功能、更改结构(如本教程系列的这一步骤所示)或重构代码时,通常会进行提交。 一个好的做法是与协作者沟通,就最适合每个人的提交粒度达成一致。
提交的频率以及将提交推送到远程存储库的频率是两个不同的问题。 在将提交推送到远程存储库前,可以在本地存储库中积累多个提交。 提交的频率取决于团队希望管理存储库的方式。
使用模板呈现页面和视图
views.py 文件中的 home
函数为页面生成纯文本 HTTP 响应。 大多数实际网页都使用丰富的 HTML 页面做出响应,这些页面通常包含实时数据。 开发人员使用函数定义视图的主要原因是动态生成内容。
视图的返回值只是一个字符串。 您可以通过使用动态内容在字符串中构建任意 HTML。 由于最好将标记与数据分开,因此最好将标记放在模板中并将数据保留在代码中。
调整视图以使用内联 HTML
第一步是转换视图处理,以便对包含一些动态内容的页面使用内联 HTML:
将 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
保存更改并再次运行应用。
刷新页面几次以确认日期和时间更新。 完成后,停止应用。
创建 HTML 模板
接下来,将页面呈现过程转换为使用 HTML 模板:
右键单击 文件夹中的 模板,然后选择“添加>新建项 以创建新文件。
在“添加新项”对话框中,选择“HTML 页面”文件模板。 将文件命名为 index.html 并选择 添加。
将 HTML 文件提供的内容替换为以下标记:
<html> <head> <title>Hello Flask</title> </head> <body> {{ content }} </body> </html>
在此代码中,
{{ content }}
语句是一个占位符或替换标记(也称为 模板变量),可在其中提供代码中的值。
调整“home”函数以加载模板
需要修改 home
函数以使用 render_template
方法。 此方法加载 HTML 模板,并使用与占位符名称匹配的命名参数为 {{ content }}
提供值。
在 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 自动查找 模板 文件夹中的模板,因此模板的路径相对于该文件夹。
保存项目更改并再次运行应用。
请注意,
content
值内的内联 HTML 语法 (\<strong>
...) 不呈现为 HTML,因为模板化引擎 (Jinja) 自动转义 HTML 内容。 自动转义可防止意外漏洞注入攻击。开发人员通常从一个页面收集输入,并使用模板占位符将其用作另一个页面中的值。 转义还充当提醒:最好将 HTML 保持在代码外。
完成后,停止应用。
使用不同的占位符
可以对 HTML 标记中的每个数据片段使用不同的占位符。 然后,再次调整 home
函数以提供特定的占位符值:
将 index.html 文件的内容替换为以下标记:
<html> <head> <title>{{ title }}</title> </head> <body> <strong>{{ message }}</strong>{{ content }} </body> </html>
在 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)
保存更改并再次运行应用。 这一次你应该会看到正确呈现的输出。
可以将更改提交到源代码管理并更新远程存储库。 有关详细信息,请参阅将更改提交到源代码管理。
单独的页面模板
模板通常保留在单独的 HTML 文件中,但也可以使用内联模板。 建议使用单独的文件,以保持标记和代码之间的清晰分离。
对模板使用 .html 扩展
页面模板文件的 .html 扩展名是完全可选的。 始终可以在 render_template
函数的第一个参数中标识文件的确切相对路径。 但是,Visual Studio(和其他编辑器)通常通过 .html 文件提供代码完成和语法着色等功能,这超过了页面模板不是 HTML 的事实。
使用 Flask 项目时,Visual Studio 会自动检测你正在编辑的 HTML 文件是否实际上是 Flask 模板,并提供某些自动完成功能。 如果开始输入 Flask 页面模板注释 ({#
),Visual Studio 会自动提供结尾 #}
字符。 注释选择 和 取消注释选择 命令(在 编辑>高级 菜单上)也使用模板注释,而不是 HTML 注释。
将模板组织到子文件夹中
可以使用子文件夹,然后在 模板下引用 文件夹下的相对路径,以调用 render_template
函数。 此方法是有效地为模板创建命名空间的好方法。