作者选择了自由与开源基金会作为写作捐赠计划的一部分接受捐赠。
引言
Flask是一个轻量级的Python网络框架,为使用Python语言创建网络应用提供了有用的工具和特性。它赋予开发者灵活性,并且对于新开发者来说是一个易于上手的框架,因为你可以仅用一个Python文件快速构建一个网络应用。Flask也是可扩展的,它不强制要求特定的目录结构,也不需要在开始前编写复杂的样板代码。
学习Flask将使你能够快速用Python创建网络应用。你可以利用Python库为你的网络应用添加高级功能,比如将数据存储在数据库中,或验证网络表单。
在本教程中,您将构建一个简单的Web应用程序,该应用程序在浏览器中渲染HTML文本。您将安装Flask,编写并运行一个Flask应用程序,并在开发模式下运行该应用程序。您将使用路由来展示服务于Web应用程序中不同目的的各种网页。您还将使用视图函数,允许用户通过动态路由与应用程序进行交互。最后,您将使用调试器来排查错误。
前提条件
-
一个本地Python 3编程环境。根据您的系统,在如何安装和设置Python 3的本地编程环境系列教程中选择适合的指南进行操作。在本教程中,我们将项目目录命名为
flask_app
。 -
了解基本的Python 3概念,例如数据类型、列表、函数以及其他相关概念。如果您不熟悉Python,请查看我们的如何在Python 3中编码系列。
-
了解基本的HTML概念。您可以回顾如何使用HTML构建网站教程系列以获取背景知识。
步骤1 — 安装Flask
在这一步中,你将激活你的Python环境,并使用pip包安装程序来安装Flask。
首先,激活你的编程环境(如果你还没有这样做):
一旦你激活了编程环境,使用pip install
命令来安装Flask:
安装完成后,你会在输出的最后部分看到已安装的包列表,类似于以下内容:
Output...
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, click, flask
Successfully installed Jinja2-3.0.1 MarkupSafe-2.0.1 Werkzeug-2.0.1 click-8.0.1 flask-2.0.1 itsdangerous-2.0.1
这意味着安装Flask的同时也安装了其他几个包。这些包是Flask执行不同功能所需的依赖项。
你已经创建了项目文件夹、虚拟环境并安装了Flask。现在可以继续设置一个简单的应用程序了。
步骤2 — 创建一个简单的应用程序
现在你已经搭建好了编程环境,接下来将开始使用 Flask。在这一步中,你将在一个 Python 文件内创建一个小型的 Flask 网络应用,并在其中编写 HTML 代码以在浏览器中显示。
在你的 flask_app
目录下,打开名为 app.py
的文件进行编辑,可以使用 nano
或你喜欢的文本编辑器:
在 app.py
文件中写入以下代码:
保存并关闭文件。
在上面的代码段中,你首先从 flask
包中导入了 Flask
对象。然后使用它来创建你的 Flask 应用实例,命名为 app
。你传递了特殊的变量 __name__
,它保存了当前 Python 模块的名称。这个名称告诉实例它的位置;Flask 需要这个信息来在后台设置一些路径。
一旦你创建了 app
实例,你就可以用它来处理传入的网络请求并向用户发送响应。@app.route
是一个装饰器,它将一个普通的 Python 函数转变为 Flask 视图函数,该视图函数将其返回值转换为 HTTP 响应,以便由 HTTP 客户端(如网络浏览器)显示。你向 @app.route()
传递值 '/'
,表示该函数将响应 URL /
的网络请求,这是主 URL。
hello()
视图函数返回字符串'<h1>Hello, World!</h1>'
作为HTTP响应。
你现在有一个简单的Flask应用程序,保存在名为app.py
的Python文件中,下一步,你将运行该应用程序,以在网页浏览器中查看hello()
视图函数的渲染结果。
步骤3 — 运行应用程序
创建包含Flask应用程序的文件后,你将使用Flask命令行接口启动开发服务器,并在浏览器中渲染你在上一步中作为hello()
视图函数返回值编写的HTML代码。
首先,在激活虚拟环境的情况下,进入你的flask_app
目录,使用FLASK_APP
环境变量告诉Flask在哪里找到应用程序(在你的例子中是app.py
),执行以下命令(在Windows上,使用set
代替export
):
然后,指定你希望在开发模式下运行应用程序(以便使用调试器捕捉错误),使用FLASK_ENV
环境变量:
最后,使用flask run
命令运行应用程序:
应用程序运行后,输出将类似于以下内容:
Output * Serving Flask app "app" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 296-353-699
上述输出包含几条信息,例如:
- 你正在运行的应用程序的名称(
"app"
)。 - 应用程序运行的环境(
development
)。 Debug mode: on
表示Flask调试器正在运行。这在开发过程中非常有用,因为它在出现问题时提供详细的错误信息,使得故障排查更加容易。- 应用程序正在本地URL
http://127.0.0.1:5000/
上运行。127.0.0.1
是代表你机器的localhost
的IP地址,而:5000
是端口号。
打开浏览器并输入URL http://127.0.0.1:5000/
。你将看到作为响应的<h1>
标题中的文本Hello, World!
。这确认了你的应用程序已成功运行。
如果你想停止开发服务器,按CTRL+C
。
警告:Flask 在开发环境中使用一个简单的 Web 服务器来运行你的应用程序,这也意味着 Flask 调试器正在运行,以便更容易捕获错误。你不应该在生产部署中使用此开发服务器。有关更多信息,请参阅 Flask 文档中的部署选项页面。你还可以查看这个使用 Gunicorn 部署 Flask 的教程或使用 uWSGI 的教程,或者你可以按照如何在 App Platform 上使用 Gunicorn 部署 Flask 应用教程,使用 DigitalOcean App Platform 来部署你的 Flask 应用程序。
要继续开发 `app.py` 应用程序,请保持开发服务器运行并打开另一个终端窗口。进入 `flask_app` 目录,激活虚拟环境,设置环境变量 `FLASK_ENV` 和 `FLASK_APP`,然后继续执行下一步。(这些命令在本步骤前面已列出。)
注意: 当打开一个新的终端,或者在你关闭正在运行开发服务器的终端并希望重新运行它时,重要的是要记住激活虚拟环境并设置环境变量 FLASK_ENV
和 FLASK_APP
,以便 flask run
命令能够正常工作。
你只需要在一个终端窗口中运行一次服务器。
当一个 Flask 应用的开发服务器已经在运行时,使用相同的 flask run
命令来运行另一个 Flask 应用是不可能的。这是因为 flask run
默认使用端口号 5000
,一旦被占用,该端口就无法用于运行另一个应用,你会收到类似以下的错误:
OutputOSError: [Errno 98] Address already in use
要解决这个问题,可以通过 CTRL+C
停止当前运行的服务器,然后再次运行 flask run
,或者如果你想同时运行两个应用,可以为 -p
参数传递一个不同的端口号,例如,要在端口 5001
上运行另一个应用,使用以下命令:
这样,你可以在 http://127.0.0.1:5000/
上运行一个应用,在 http://127.0.0.1:5001/
上运行另一个应用,如果你愿意的话。
现在你拥有了一个小型的 Flask 网页应用。你已经运行了你的应用并在网页浏览器上显示了信息。接下来,你将学习有关路由的知识,以及如何使用它们来服务多个网页。
第四步 — 路由和视图函数
在这一步中,你将为应用添加几个路由,以便根据请求的URL显示不同的页面。你还将学习视图函数的概念以及如何使用它们。
一个路由是你可以用来确定用户在浏览器中访问你的Web应用时所获取内容的URL。例如,http://127.0.0.1:5000/
可能是用于显示主页的主要路由。URL http://127.0.0.1:5000/about
可能是用于关于页面的另一个路由,向访问者提供有关你的Web应用的一些信息。同样,你可以创建一个允许用户在http://127.0.0.1:5000/login
登录你的应用的路由。
你当前的Flask应用只有一个路由,用于服务请求主URL (http://127.0.0.1:5000/
) 的用户。为了演示如何向应用添加新的网页,你将编辑应用文件,添加另一个路由,该路由在http://127.0.0.1:5000/about
提供有关你的Web应用的信息。
首先,打开你的app.py
文件进行编辑:
编辑文件,在文件末尾添加以下高亮代码:
保存并关闭文件。
你添加了一个名为 about()
的新函数。此函数通过 @app.route()
装饰器被转换为一个视图函数,负责处理对 http://127.0.0.1:5000/about
端点的请求。
在开发服务器运行的情况下,使用浏览器访问以下 URL:
http://127.0.0.1:5000/about
你将看到文本 This is a Flask web application.
以 <h3>
HTML 标题的形式呈现。
你还可以为一个视图函数设置多个路由。例如,你可以同时在 /
和 /index/
提供首页。为此,打开你的 app.py
文件进行编辑:
通过向 hello()
视图函数添加另一个装饰器来编辑文件:
保存并关闭文件。
添加此新装饰器后,你可以在 http://127.0.0.1:5000/
和 http://127.0.0.1:5000/index
两个地址访问首页。
现在你了解了什么是路由,如何使用它们创建视图函数,以及如何向应用程序添加新路由。接下来,你将使用动态路由,让用户能够控制应用程序的响应。
步骤 5 — 动态路由
在这一步中,您将使用动态路由来允许用户与应用程序进行交互。您将创建一个路由,用于将通过URL传递的单词大写,并创建另一个路由,用于将两个数字相加并显示结果。
通常情况下,用户不会通过手动编辑URL来与Web应用程序交互。相反,用户通过页面上的元素进行交互,这些元素会根据用户的输入和操作导向不同的URL。但为了本教程的目的,您将编辑URL以演示应用程序如何根据不同的URL做出不同的响应。
首先,打开您的app.py
文件进行编辑:
如果您允许用户向您的Web应用程序提交内容,比如您将在接下来的编辑中通过URL传递的值,您应该始终记住,应用程序不应直接显示不受信任的数据(用户提交的数据)。为了安全地显示用户数据,请使用markupsafe
包附带的escape()
函数,该包在安装Flask时一同被安装。
编辑app.py
文件,并在文件顶部、Flask
导入语句上方添加以下行:
然后,在文件末尾添加以下路由:
保存并关闭文件。
这条新路由包含一个可变部分 `<word>
`。它指示 Flask 从 URL 中提取值并传递给视图函数。URL 变量 `<word>
` 将关键字参数传递给 `capitalize()
` 视图函数。该参数与 URL 变量同名(本例中为 `word
`)。通过这种方式,你可以访问通过 URL 传递的单词,并使用 Python 中的 `capitalize()
` 方法响应其大写版本。
你使用之前导入的 `escape()
` 函数将 `word
` 字符串渲染为文本。这一点至关重要,以防止跨站脚本(XSS)攻击。如果用户提交的是恶意 JavaScript 而非单词,`escape()
` 会将其渲染为文本,浏览器不会执行它,从而确保你的 Web 应用安全。
为了在 `<h1>
` HTML 标题中显示大写的单词,你使用了 Python 的 `format()
` 方法。更多关于此方法的信息,请参阅如何在 Python 3 中使用字符串格式化工具
在开发服务器运行的情况下,打开浏览器并访问以下 URL。你可以将高亮显示的单词替换为你选择的任意单词。
http://127.0.0.1:5000/capitalize/hello
http://127.0.0.1:5000/capitalize/flask
http://127.0.0.1:5000/capitalize/python
你将在页面上的 `<h1>
` 标签中看到 URL 中的单词已大写。
您还可以在路由中使用多个变量。为了演示这一点,您将添加一个路由,该路由将两个正整数相加并显示结果。
打开您的app.py
文件进行编辑:
在文件末尾添加以下路由:
保存并关闭文件。
在这个路由中,您使用了一个特殊转换器int
与URL变量(/add/<int:n1>/<int:n2>/
),它仅接受正整数。默认情况下,URL变量被假定为字符串并按字符串处理。
在开发服务器运行的情况下,打开浏览器并访问以下URL:
http://127.0.0.1:5000/add/5/5/
结果将是这两个数字的和(在本例中为10
)。
现在,您已经了解了如何使用动态路由根据请求的URL在单一路由中显示不同的响应。接下来,您将学习如何在出现错误时调试您的Flask应用程序。
步骤6 — 调试Flask应用程序
在开发Web应用程序时,您经常会遇到应用程序显示错误而不是您期望的行为的情况。您可能会拼错变量或忘记定义或导入函数。为了使解决这些问题变得更容易,Flask在开发模式下运行应用程序时提供了一个调试器。在这一步中,您将学习如何使用Flask调试器修复应用程序中的错误。
为了演示如何处理错误,您将创建一个路由,从用户名列表中向用户打招呼。
打开您的app.py
文件进行编辑:
在文件末尾添加以下路由:
保存并关闭文件。
在上面的路由中,greet_user()
视图函数从user_id
URL变量接收一个user_id
参数。您使用int
转换器来接受正整数。在函数内部,您有一个名为users
的Python列表,其中包含三个表示用户名的字符串。视图函数根据提供的user_id
返回一个字符串。如果user_id
是0
,响应将是Hi Bob
,并用<h2>
标签包裹,因为Bob
是列表中的第一个项目(即users[0]
的值)。
在开发服务器运行的情况下,打开浏览器并访问以下URL:
http://127.0.0.1:5000/users/0
http://127.0.0.1:5000/users/1
http://127.0.0.1:5000/users/2
您将收到以下响应:
OutputHi Bob
Hi Jane
Hi Adam
到目前为止,这种方法运行良好,但当你请求一个不存在的用户的问候时,它可能会出错。为了演示Flask调试器的工作原理,请访问以下URL:
http://127.0.0.1:5000/users/3
你会看到一个类似这样的页面:
在页面顶部,你会看到Python异常的名称,即IndexError
,这表明列表索引(在本例中为3
)超出了列表的范围(因为列表只有三个元素,索引范围仅从0
到2
)。在调试器中,你可以看到追溯信息,它告诉你引发此异常的代码行。
追溯信息的最后两行通常指出了错误源头。在你的情况下,这些行可能类似于以下内容:
File "/home/USER/flask_app/app.py", line 28, in greet_user
return '<h2>Hi {}</h2>'.format(users[user_id])
这表明错误源自app.py
文件中的greet_user()
函数,特别是在return
语句处。
了解引发异常的原始行将有助于你确定代码中哪里出了问题,并决定如何修复它。
在这种情况下,你可以使用一个简单的try...except
语句来修复这个错误。如果请求的URL索引超出了列表范围,用户将收到一个404 Not Found错误,这是一个HTTP错误,告诉用户他们所查找的页面不存在。
打开你的app.py
文件进行编辑:
要返回HTTP 404错误,你需要使用Flask的abort()
函数,该函数可用于生成HTTP错误响应。修改文件中的第二行,同时导入此函数:
接着编辑greet_user()
视图函数,使其如下所示:
你在上方使用try
来测试return
表达式是否存在错误。如果没有错误,即user_id
的值与users
列表中的某个索引相匹配,应用程序将返回相应的问候。如果user_id
的值超出了列表范围,则会引发IndexError
异常,你使用except
捕获该错误,并通过Flask的abort()
辅助函数响应HTTP 404错误。
现在,当开发服务器运行时,再次访问该URL:
http://127.0.0.1:5000/users/3
这次你会看到一个标准的404错误页面,告知用户该页面不存在。
本教程结束时,你的app.py
文件将如下所示:
至此,你已大致了解如何使用Flask调试器来排查错误,并帮助你确定解决这些错误的适当措施。
总结
你现在对 Flask 有了一个大致的了解,知道如何安装它,如何用它编写一个 Web 应用,如何运行开发服务器,以及如何使用路由和视图函数来展示服务于特定目的的不同网页。你也学会了如何使用动态路由让用户通过 URL 与你的 Web 应用进行互动,以及如何利用调试器来排查错误。
如果你想进一步了解 Flask,可以访问Flask 主题页面。