作者选择了自由与开源基金会作为写作捐赠计划的一部分接受捐款。
引言
网页表单,如文本字段和文本区域,允许用户向您的应用程序发送数据,以便执行操作,或提交较大篇幅的文本。例如,在社交媒体应用中,您可能会为用户提供一个框,让他们可以添加新内容到他们的页面。另一个例子是登录页面,您会为用户提供一个文本字段来输入用户名,以及一个密码字段来输入密码。服务器(本例中为您的Flask应用)会使用用户提交的数据,如果数据有效则允许用户登录,否则会返回如无效凭证!
的信息,告知用户提交的数据不正确。
Flask 是一个轻量级的 Python Web 框架,为使用 Python 语言创建 Web 应用程序提供了有用的工具和功能。在本教程中,您将构建一个小型 Web 应用程序,演示如何使用 Web 表单。该应用程序将有一个页面用于显示存储在 Python 列表中的消息,以及一个页面用于添加新消息。您还将使用 消息闪现 来通知用户在提交无效数据时发生的错误。
前提条件
-
一个本地 Python 3 编程环境,请根据您的发行版在 如何安装和设置 Python 3 的本地编程环境 系列中按照教程操作。在本教程中,我们将项目目录称为
flask_app
。 -
了解基本的Flask概念,例如路由、视图函数和模板。如果您不熟悉Flask,请查看如何使用Flask和Python创建您的第一个Web应用程序以及如何在Flask应用程序中使用模板。
-
了解基本的HTML概念。您可以回顾我们的如何使用HTML构建网站教程系列以获取背景知识。
第一步 —— 显示消息
在这一步中,你将创建一个Flask应用程序,其首页用于显示存储在Python字典列表中的消息。
首先,打开一个名为app.py
的新文件进行编辑:
在app.py
文件中添加以下代码,创建一个带有单一路由的Flask服务器:
保存并关闭文件。
在此文件中,你首先从flask
包中导入了Flask
类和render_template()
函数。然后,使用Flask
类创建了一个名为app
的应用实例,传入了特殊的__name__
变量,Flask需要这个变量来在幕后设置一些路径。模板渲染的内容在教程如何在Flask应用中使用模板中有详细介绍。
接着,你创建了一个名为messages
的全局Python列表,其中包含字典。每个字典包含两个键:title
用于消息标题,content
用于消息内容。这是一个简化的数据存储示例;在实际应用中,你会使用一个持久化存储数据的数据库,并能更高效地操作这些数据。
在创建了Python列表后,您使用@app.route()
装饰器来创建一个名为index()
的视图函数。在其中,您返回对render_template()
函数的调用,这指示Flask该路由应显示一个HTML模板。您将此模板命名为index.html
(稍后将创建它),并向其传递一个名为messages
的变量。该变量持有您之前声明的messages
列表作为其值,并使其对HTML模板可用。视图函数在教程如何使用Flask和Python 3创建您的第一个Web应用程序中有详细介绍。
接下来,在您的flask_app
目录中创建一个templates
文件夹,Flask会在其中搜索模板,然后打开一个名为base.html
的模板文件,该文件将包含其他模板继承的代码以避免代码重复:
在base.html
文件中添加以下代码,以创建带有导航栏和内容块的基础模板:
保存并关闭文件。
这个基础模板包含了所有你需要在其他模板中重复使用的HTML样板代码。`title`块将被替换以设置每个页面的标题,而`content`块将被替换为每个页面的内容。导航栏有两个链接,一个是索引页面,你使用`url_for()`辅助函数链接到`index()`视图函数,另一个是关于页面(如果你选择在应用中包含的话)。
接下来,打开一个名为`index.html`的模板。这是你在`app.py`文件中引用的模板:
向其中添加以下代码:
保存并关闭文件。
在这段代码中,你扩展了`base.html`模板并替换了`content`块的内容。你使用了一个`
`标题,同时也作为页面的标题。
你在`{% for message in messages %}`这一行中使用了Jinja的`for`循环来遍历`messages`列表中的每条消息。你使用了一个`
`标题中,内容显示在一个`
`标签中。
在你的虚拟环境激活的情况下,在`flask_app`目录中,使用`FLASK_APP`环境变量告诉Flask关于应用的信息(在本例中是`app.py`):
接着,将FLASK_ENV
环境变量设置为development
,以便在开发模式下运行应用程序并启用调试器。有关Flask调试器的更多信息,请参阅如何在Flask应用程序中处理错误。使用以下命令进行设置(在Windows上,使用set
代替export
):
接下来,运行应用程序:
开发服务器启动后,通过浏览器访问以下URL:
http://127.0.0.1:5000/
你将在索引页上看到messages
列表中的消息:
现在你已经搭建了Web应用程序并展示了消息,接下来需要一种方式让用户能够向索引页添加新消息。这可以通过网页表单来实现,你将在下一步中进行设置。
步骤2 — 设置表单
在这一步中,你将在应用程序中创建一个页面,允许用户通过网页表单向消息列表添加新消息。
保持开发服务器运行,并打开一个新的终端窗口。
首先,打开你的app.py
文件:
在文件末尾添加以下路由:
保存并关闭文件。
这个 `/create
` 路由具有 `methods
` 参数,其值为元组 `('GET', 'POST')
`,以接受 `GET
` 和 `POST
` 请求。`GET
` 和 `POST
` 是 `HTTP 方法`。默认情况下,仅接受 `GET
` 请求,这些请求用于检索数据,例如向服务器请求索引页或关于页。`POST
` 请求用于向特定路由提交数据,这通常会改变服务器上的数据。
在此示例中,您将使用 `GET
` 请求请求 `create
` 页面。Create 页面将包含一个带有输入字段和提交按钮的网页表单。当用户填写网页表单并点击提交按钮时,会向 `/create
` 路由发送 `POST
` 请求。在那里处理请求,验证提交的数据以确保用户未提交空表单,并将其添加到 `messages
` 列表中。
`create()
` 视图函数目前只做一件事:在接收到常规 GET 请求时渲染名为 `create.html
` 的模板。您现在将创建此模板,然后在下一步中编辑该函数以处理 `POST
` 请求。
打开一个名为 `create.html
` 的新模板文件:
向其中添加以下代码:
保存并关闭文件。
在这段代码中,你扩展了 `base.html
` 模板,并用一个 `<h1>
` 标题替换了 `content
` 块,该标题作为页面的标题。在 `<form>
` 标签中,你将 `method
` 属性设置为 `post
`,以便表单数据作为 `POST
` 请求发送到服务器。
在表单中,你有一个名为 `title
` 的文本输入字段;这是你在应用程序中用来访问标题表单数据的名字。你为 `<input>
` 标签设置了一个 `value
` 为 `{{ request.form['title'] }}
`。这很有用,可以恢复用户输入的数据,以防万一出现问题时数据不会丢失。例如,如果用户忘记了填写必需的 `content
` 文本区域,请求会被发送到服务器,并返回一个错误消息作为响应,但标题中的数据不会丢失,因为它会被保存在 `request
` 全局对象中,可以通过 `request.form['title']
` 访问。
在标题输入字段之后,你添加了一个名为 `content
` 的文本区域,其值为 `{{ request.form['content'] }}
`,原因如前所述。
最后,你在表单末尾添加了一个提交按钮。
现在,在开发服务器运行的情况下,使用浏览器导航到 `/create
` 路由:
http://127.0.0.1:5000/create
你会看到一个“添加新消息”页面,其中有一个用于消息标题的输入字段,一个用于消息内容的文本区域,以及一个提交按钮。
此表单向你的 `create()` 视图函数提交一个 `POST` 请求。然而,该函数中尚无处理 `POST` 请求的代码,因此在填写表单并提交后没有任何反应。下一步,你将处理表单提交时传入的 `POST` 请求。你将检查提交的数据是否有效(非空),并将消息标题和内容添加到 `messages` 列表中。
步骤 3 — 处理表单请求
在这一步中,你将在应用端处理表单请求。你将通过上一步创建的表单访问用户提交的数据,并将其添加到消息列表中。你还将使用消息闪现功能,在用户提交无效数据时通知他们。闪现消息仅显示一次,并在下一个请求时消失(例如,如果你导航到另一个页面)。
打开 app.py
文件进行编辑:
首先,从 Flask 框架导入以下内容:
- 全局
request
对象,用于访问上一步构建的 HTML 表单提交的传入请求数据。 url_for()
函数用于生成URL。flash()
函数用于在请求处理后闪现一条消息(告知用户一切顺利,或在提交的数据无效时通知他们存在问题)。redirect()
函数用于将客户端重定向到其他位置。
将这些导入添加到文件的第一行:
flash()
函数将闪现消息存储在客户端的浏览器会话中,这需要设置一个密钥。此密钥用于保护会话,使Flask能够记住从一个请求到另一个请求的信息,例如从新消息页面转到索引页面。用户可以访问存储在会话中的信息,但不能修改,除非他们拥有密钥,因此绝不能让任何人访问你的密钥。更多信息请参阅Flask会话文档。
密钥应是一个长随机字符串。你可以使用os
模块中的os.urandom()
方法生成密钥,该方法返回适用于加密用途的随机字节字符串。要使用它获取随机字符串,请打开一个新的终端并使用以下命令启动Python交互式 shell:
在Python交互式 shell 中,从标准库导入os
模块,并按如下方式调用os.urandom()
方法:
你将得到类似以下内容的字符串:
Output
'df0331cefc6c2b9a5d0208a726a5d1c0fd37324feba25506'
你可以将获得的字符串用作你的密钥。
要设置密钥,通过app.config
对象为你的应用添加一个SECRET_KEY
配置。在定义messages
变量之前,紧跟在app
定义之后直接添加它:
接下来,修改create()
视图函数,使其完全如下所示:
在if
语句中,通过比较request.method == 'POST'
确保仅当请求为POST
请求时执行其后的代码。
接着,从request.form
对象中提取提交的标题和内容,该对象使您能够访问请求中的表单数据。如果未提供标题,条件if not title
将被满足。在这种情况下,您将使用flash()
函数向用户显示一条消息,告知他们标题是必需的。这会将消息添加到闪现消息列表中。稍后,您将在base.html
模板中显示这些消息。同样,如果未提供内容,条件elif not content
将被满足。如果是这样,您将'内容是必需的!'
消息添加到闪现消息列表中。
如果消息的标题和内容已正确提交,您将使用messages.append({'title': title, 'content': content})
语句将一个新字典添加到messages
列表中,其中包含用户提供的标题和内容。然后,使用redirect()
函数将用户重定向到索引页面。您使用url_for()
函数链接到索引页面。
保存并关闭文件。
现在,使用您的网络浏览器导航到/create
路由:
http://127.0.0.1:5000/create
在表单中填写您选择的标题和一些内容。提交表单后,您将在索引页上看到新消息的列表。
最后,您将在base.html
模板中显示闪现消息,并在导航栏中添加“新消息”页面的链接,以便轻松访问此新页面。打开基础模板文件:
编辑文件,在导航栏内的FlaskApp链接后添加一个新的 `<a>
` 标签。然后在 `<nav>
` 标签内添加一个新的 `for
` 循环,直接在 `content
` 块上方显示闪现消息。这些消息可通过Flask提供的特殊函数 `get_flashed_messages()
` 获取。接着为每条消息添加一个名为 `alert
` 的类属性,并在 `<style>
` 标签内赋予其一些CSS属性:
保存并关闭文件,然后在浏览器中重新加载 `https://127.0.0.1:5000
`。导航栏现在将有一个链接到 `/create
` 路由的“创建”项。
要查看闪现消息的工作原理,请转到“创建”页面,并点击提交按钮而不填写两个字段。您将收到如下所示的消息:
返回索引页面,您会看到导航栏下方的闪现消息消失了,尽管它们作为基础模板的一部分显示出来。如果不是闪现消息,它们也会在索引页面上显示,因为索引页面也继承自基础模板。
尝试提交一个带有标题但没有内容的表单,你会看到消息“内容是必需的!”。点击导航栏中的FlaskApp链接返回首页,然后点击浏览器的返回按钮回到创建页面。你会发现提示消息仍然存在。这仅在点击返回按钮时有效,因为它保存了之前的请求。如果在导航栏中点击创建链接,则会发送一个新的请求,这将清空表单,因此闪现的消息也会消失。
现在你知道了如何接收用户输入、如何验证它,以及如何将其添加到数据源中。
注意:
你添加到messages
列表中的消息在服务器停止时会消失,因为Python列表仅保存在内存中。若要永久保存你的消息,你需要使用SQLite等数据库。查看如何在Python 3中使用sqlite3模块以学习如何使用SQLite与Python。
结论
你创建了一个Flask应用,用户可以在首页显示的消息列表中添加消息。你创建了一个网页表单,处理用户通过表单提交的数据,并将其添加到你的消息列表中。你还使用了闪现消息来通知用户在提交无效数据时的错误。
若想深入了解 Flask,不妨查阅Flask系列中的其他教程。
Source:
https://www.digitalocean.com/community/tutorials/how-to-use-web-forms-in-a-flask-application