如何使用Flask和Python3创建您的第一个Web应用程序
作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。
介绍
Flask 是一个轻量级的 Python Web 框架,它为使用 Python 语言创建 Web 应用程序提供了有用的工具和功能。 它为开发人员提供了灵活性,并且是新开发人员可访问的框架,因为您只需使用单个 Python 文件即可快速构建 Web 应用程序。 Flask 也是可扩展的,在开始之前不会强制使用特定的目录结构或需要复杂的样板代码。
学习 Flask 将允许您在 Python 中快速创建 Web 应用程序。 您可以利用 Python 库向 Web 应用程序添加高级功能,例如将数据存储在数据库中或验证 Web 表单。
在本教程中,您将构建一个在浏览器上呈现 HTML 文本的小型 Web 应用程序。 您将安装 Flask,编写和运行 Flask 应用程序,并在开发模式下运行该应用程序。 您将使用路由来显示在您的 Web 应用程序中用于不同目的的各种网页。 您还将使用视图函数来允许用户通过动态路由与应用程序交互。 最后,您将使用调试器来解决错误。
先决条件
- 本地 Python 3 编程环境。 按照 如何为 Python 3 系列安装和设置本地编程环境中的分发教程进行操作。 在本教程中,我们将调用我们的项目目录
flask_app
。 - 了解基本的 Python 3 概念,例如 数据类型、 列表、 函数 和其他此类概念。 如果您不熟悉 Python,请查看我们的 如何在 Python 3 中编码。
- 了解基本的 HTML 概念。 您可以查看 如何使用 HTML 构建网站 教程系列以获取背景知识。
第 1 步 — 安装 Flask
在此步骤中,您将激活 Python 环境并使用 pip 包安装程序安装 Flask。
首先,如果您还没有激活您的编程环境:
source env/bin/activate
激活编程环境后,使用 pip install
命令安装 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 Web 应用程序,您将在其中编写 HTML 代码以在浏览器上显示。
在您的 flask_app
目录中,打开一个名为 app.py
的文件进行编辑,使用 nano
或您喜欢的文本编辑器:
nano app.py
在 app.py
文件中写入以下代码:
烧瓶应用程序/app.py
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return '<h1>Hello, World!</h1>'
保存并关闭文件。
在上面的代码块中,首先从 flask
包中导入 Flask
对象。 然后,您使用它来创建您的 Flask 应用程序实例,并将其命名为 app
。 您传递特殊变量 __name__
,它保存当前 Python 模块的名称。 这个名字告诉实例它所在的位置; 你需要这个,因为 Flask 在幕后设置了一些路径。
创建 app
实例后,您可以使用它来处理传入的 Web 请求并向用户发送响应。 @app.route
是一个 装饰器,它将常规 Python 函数转换为 Flask 视图函数,它将函数的返回值转换为 HTTP 响应以由 HTTP 客户端显示,例如网络浏览器。 您将值 '/'
传递给 @app.route()
表示此函数将响应对 URL /
的 Web 请求,这是主 URL。
hello()
视图函数返回字符串 '<h1>Hello, World!</h1>'
作为 HTTP 响应。
您现在在名为 app.py
的 Python 文件中有一个简单的 Flask 应用程序,在下一步中,您将运行该应用程序以查看在 Web 浏览器中呈现的 hello()
视图函数的结果。
第 3 步 — 运行应用程序
创建包含 Flask 应用程序的文件后,您将使用 Flask 命令行界面运行它以启动开发服务器并在浏览器上呈现您编写的 HTML 代码作为 hello()
视图函数的返回值在上一步中。
首先,在激活虚拟环境的 flask_app
目录中,使用 FLASK_APP
环境变量和以下命令告诉 Flask 在哪里可以找到应用程序(在您的情况下为 app.py
) (在 Windows 上,使用 set
而不是 export
):
export FLASK_APP=app
然后使用 FLASK_ENV
环境变量指定您要在开发模式下运行应用程序(以便您可以使用调试器捕获错误):
export FLASK_ENV=development
最后,使用 flask run
命令运行应用程序:
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 或者您可以使用 DigitalOcean App Platform 来部署您的 Flask 应用程序,按照 如何部署Flask App Using Gunicorn to App Platform 教程。
要继续开发 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
上运行另一个应用程序,请使用以下命令:
flask run -p 5001
有了这个,您可以在 http://127.0.0.1:5000/
上运行一个应用程序,如果您愿意,可以在 http://127.0.0.1:5001/
上运行另一个应用程序。
您现在有一个小型 Flask Web 应用程序。 您已经运行了应用程序并在 Web 浏览器上显示了信息。 接下来,您将了解路由以及如何使用它们来服务多个网页。
第 4 步 - 路由和视图功能
在此步骤中,您将向应用程序添加一些路由,以根据请求的 URL 显示不同的页面。 您还将了解视图函数以及如何使用它们。
route 是一个 URL,可用于确定用户在浏览器上访问您的 Web 应用程序时收到的内容。 例如,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
文件进行编辑:
nano app.py
通过在文件末尾添加以下突出显示的代码来编辑文件:
烧瓶应用程序/app.py
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return '<h1>Hello, World!</h1>' @app.route('/about/') def about(): return '<h3>This is a Flask web application.</h3>'
保存并关闭文件。
您添加了一个名为 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
文件进行编辑:
nano app.py
通过向 hello()
视图函数添加另一个装饰器来编辑文件:
烧瓶应用程序/app.py
from flask import Flask app = Flask(__name__) @app.route('/') @app.route('/index/') def hello(): return '<h1>Hello, World!</h1>' @app.route('/about/') def about(): return '<h3>This is a Flask web application.</h3>'
保存并关闭文件。
添加此新装饰器后,您可以在 http://127.0.0.1:5000/
和 http://127.0.0.1:5000/index
处访问索引页面。
您现在了解了路由是什么,如何使用它们来创建视图功能,以及如何向应用程序添加新路由。 接下来,您将使用动态路由来允许用户控制应用程序的响应。
第 5 步 — 动态路由
在此步骤中,您将使用动态路由来允许用户与应用程序交互。 您将创建一个将通过 URL 传递的单词大写的路由,以及一个将两个数字相加并显示结果的路由。
通常,用户不会通过手动编辑 URL 来与 Web 应用程序交互。 相反,用户与页面上的元素进行交互,这些元素会根据用户的输入和操作导致不同的 URL,但出于本教程的目的,您将编辑 URL 以演示如何使应用程序对不同的 URL 做出不同的响应。
首先,打开您的 app.py
文件进行编辑:
nano app.py
如果您允许用户向您的 Web 应用程序提交某些内容,例如您将在以下编辑中执行的 URL 中的值,您应始终牢记,您的应用程序不应直接显示不受信任的数据(用户数据提交)。 要安全地显示用户数据,请使用随 Flask 一起安装的 markupsafe
软件包附带的 escape()
函数。
编辑 app.py
并将以下行添加到文件顶部,在 Flask
导入上方:
烧瓶应用程序/app.py
from markupsafe import escape from flask import Flask # ...
然后,将以下路由添加到文件末尾:
烧瓶应用程序/app.py
# ... @app.route('/capitalize/<word>/') def capitalize(word): return '<h1>{}</h1>'.format(escape(word.capitalize()))
保存并关闭文件。
这条新路线有一个可变部分 <word>
。 这告诉 Flask 从 URL 中获取值并将其传递给视图函数。 URL 变量 <word>
将关键字参数传递给 capitalize()
视图函数。 该参数与 URL 变量具有相同的名称(在本例中为 word
)。 有了这个,您可以访问通过 URL 传递的单词,并使用 Python 中的 capitalize()
方法以大写版本进行响应。
您使用之前导入的 escape()
函数将 word
字符串呈现为文本。 这对于避免 跨站点脚本 (XSS) 攻击 很重要。 如果用户提交恶意 JavaScript 而不是一个单词,escape()
将它呈现为文本,浏览器将不会运行它,从而保证您的 Web 应用程序的安全。
要在 <h1>
HTML 标题中显示大写单词,请使用 format()
Python 方法,有关此方法的更多信息,请参阅 如何在 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
文件进行编辑:
nano app.py
将以下路由添加到文件末尾:
烧瓶应用程序/app.py
# ... @app.route('/add/<int:n1>/<int:n2>/') def add(n1, n2): return '<h1>{}</h1>'.format(n1 + n2)
保存并关闭文件。
在此路由中,您使用带有 URL 变量 (/add/<int:n1>/<int:n2>/
) 的 特殊转换器 int
,它只接受正整数。 默认情况下,URL 变量被假定为字符串并被视为字符串。
在开发服务器运行的情况下,打开浏览器并访问以下 URL:
http://127.0.0.1:5000/add/5/5/
结果将是两个数字的总和(在本例中为 10
)。
您现在已经了解了如何使用动态路由根据请求的 URL 在单个路由中显示不同的响应。 接下来,您将学习如何在出现错误时对 Flask 应用程序进行故障排除和调试。
第 6 步 — 调试 Flask 应用程序
在开发 Web 应用程序时,您会经常遇到应用程序显示错误而不是您期望的行为的情况。 您可能拼错变量或忘记定义或导入函数。 为了更容易解决这些问题,Flask 在开发模式下运行应用程序时提供了一个调试器。 在此步骤中,您将学习如何使用 Flask 调试器修复应用程序中的错误。
为了演示如何处理错误,您将创建一个从用户名列表中问候用户的路由。
打开 app.py
文件进行编辑:
nano app.py
将以下路由添加到文件末尾:
烧瓶应用程序/app.py
# ... @app.route('/users/<int:user_id>/') def greet_user(user_id): users = ['Bob', 'Jane', 'Adam'] return '<h2>Hi {}</h2>'.format(users[user_id])
保存并关闭文件。
在上面的路由中,greet_user()
视图函数接收来自 user_id
URL 变量的 user_id
参数。 您使用 int
转换器来接受正整数。 在函数内部,您有一个名为 users
的 Python 列表,其中包含三个代表用户名的字符串。 view 函数返回一个根据提供的 user_id
构造的字符串。 如果 user_id
是 0
,则响应将是 <h2>
标记中的 Hi Bob
,因为 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
文件进行编辑:
nano app.py
要响应 HTTP 404 错误,您需要 Flask 的 abort() 函数,该函数可用于做出 HTTP 错误响应。 更改文件中的第二行以导入此函数:
烧瓶应用程序/app.py
from markupsafe import escape from flask import Flask, abort
然后编辑greet_user()
视图函数如下:
烧瓶应用程序/app.py
# ... @app.route('/users/<int:user_id>/') def greet_user(user_id): users = ['Bob', 'Jane', 'Adam'] try: return '<h2>Hi {}</h2>'.format(users[user_id]) except IndexError: abort(404)
您使用上面的 try
来测试 return
表达式是否有错误。 如果没有错误,这意味着 user_id
的值与 users
列表中的索引匹配,应用程序将以适当的问候语进行响应。 如果 user_id
的值超出列表的范围,将引发 IndexError
异常,您使用 except
捕获错误并使用 HTTP 404 错误响应abort()
烧瓶辅助函数。
现在,随着开发服务器的运行,再次访问 URL:
http://127.0.0.1:5000/users/3
这次您将看到一个标准的 404 错误页面,通知用户该页面不存在。
在本教程结束时,您的 app.py
文件将如下所示:
烧瓶应用程序/app.py
from markupsafe import escape from flask import Flask, abort app = Flask(__name__) @app.route('/') @app.route('/index/') def hello(): return '<h1>Hello, World!</h1>' @app.route('/about/') def about(): return '<h3>This is a Flask web application.</h3>' @app.route('/capitalize/<word>/') def capitalize(word): return '<h1>{}</h1>'.format(escape(word.capitalize())) @app.route('/add/<int:n1>/<int:n2>/') def add(n1, n2): return '<h1>{}</h1>'.format(n1 + n2) @app.route('/users/<int:user_id>/') def greet_user(user_id): users = ['Bob', 'Jane', 'Adam'] try: return '<h2>Hi {}</h2>'.format(users[user_id]) except IndexError: abort(404)
您现在对如何使用 Flask 调试器来解决您的错误并帮助您确定适当的操作过程来修复它们有了一个大致的了解。
结论
您现在已经大致了解了 Flask 是什么,如何安装它,以及如何使用它来编写 Web 应用程序,如何运行开发服务器,以及如何使用路由和视图函数来显示服务于特定的不同网页目的。 您还学习了如何使用动态路由来允许用户通过 URL 与您的 Web 应用程序交互,以及如何使用调试器来解决错误。
如果您想了解更多关于 Flask 的信息,请查看 Flask 主题页面。