如何在 Flask 应用程序中使用网络表单

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

网页表格,如文本字段和文本区域,允许用户将数据发送到您的应用程序,以便使用它执行操作,或向应用程序发送更大的文本区域。例如,在社交媒体应用程序中,您可以给用户一个框,让他们可以将新内容添加到他们的页面。另一个例子是登录页面,您会给用户一个文本字段输入他们的用户名和一个密码字段输入他们的密码。

Flask是一个轻量级的Python网页框架,提供用于在Python语言中创建网页应用程序的有用工具和功能。 在本教程中,您将构建一个小型网页应用程序,展示如何使用网页表格。

前提条件

步骤 1 - 显示消息

在此步骤中,您将创建一个Flask应用程序,具有索引页面,用于显示存储在Python字典列表中的消息。

首先打开一个名为app.py的新文件来编辑:

1nano app.py

在 app.py 文件中添加以下代码,以创建一个单一路径的 Flask 服务器:

 1[label flask_app/app.py]
 2from flask import Flask, render_template
 3
 4app = Flask(__name__)
 5
 6messages = [{'title': 'Message One',
 7             'content': 'Message One Content'},
 8            {'title': 'Message Two',
 9             'content': 'Message Two Content'}
10            ]
11
12@app.route('/')
13def index():
14    return render_template('index.html', messages=messages)

保存并关闭文件。

在此文件中,您首先从flask包中导入Flask类和render_template()函数,然后使用Flask类创建一个名为app的新应用程序实例,通过特殊的__name__变量,这需要Flask在幕后设置一些路径。

然后你创建一个名为消息的全球Python列表,其中包含Python字典。每个字典都有两个密钥:信息标题的标题和信息内容的内容

在创建 Python 列表后,您使用 @app.route() 装饰器创建一个名为 index() 的 _view 函数。在其中,您返回了对 render_template() 函数的呼叫,该函数向 Flask 表示该路径应该显示一个 HTML 模板。您将这个模板命名为 index.html (您将稍后创建它),并将一个名为 messages 的变量传递给它。这个变量将您之前宣布的 messages 列表作为一个值,并使其可用于 HTML 模板。 查看功能包含在教程中(How To Create Your First Web Application Using Flask and Python 3](LINK)。

接下来,在您的flask_app目录中创建一个模板文件夹,Flask 搜索模板,然后打开名为base.html的模板文件,该文件将包含其他模板继承的代码,以避免代码重复:

1mkdir templates
2nano templates/base.html

将下列代码添加到 base.html 文件中,以创建一个 navbar 和一个内容块的 base 模板:

 1[label flask_app/templates/base.html]
 2
 3<!DOCTYPE html>
 4<html lang="en">
 5<head>
 6    <meta charset="UTF-8">
 7    <title>{% block title %} {% endblock %} - FlaskApp</title>
 8    <style>
 9        .message {
10            padding: 10px;
11            margin: 5px;
12            background-color: #f3f3f3
13        }
14        nav a {
15            color: #d64161;
16            font-size: 3em;
17            margin-left: 50px;
18            text-decoration: none;
19        }
20
21    </style>
22</head>
23<body>
24    <nav>
25        <a href="{{ url_for('index') }}">FlaskApp</a>
26        <a href="#">About</a>
27    </nav>
28    <hr>
29    <div class="content">
30        {% block content %} {% endblock %}
31    </div>
32</body>
33</html>

保存并关闭文件。

此基础模板包含您在其他模板中需要重复使用的所有HTML锅炉板。标题块将被更换为为每个页面设置一个标题,而内容块将被替换为每个页面的内容。导航栏有两个链接,一个用于索引页面,其中您使用url_for()辅助函数链接到index()视图函数,另一个用于关于页面,如果您选择在应用程序中包含一个链接。

接下来,打开一个名为index.html的模板,这是你在app.py文件中提到的模板:

1nano templates/index.html

添加以下代码:

 1[label flask_app/templates/index.html]
 2{% extends 'base.html' %}
 3
 4{% block content %}
 5    <h1>{% block title %} Messages {% endblock %}</h1>
 6    {% for message in messages %}
 7        <div class='message'>
 8            <h3>{{ message['title'] }}</h3>
 9            <p>{{ message['content'] }}</p>
10        </div>
11    {% endfor %}
12{% endblock %}

保存并关闭文件。

在这个代码中,你扩展了base.html模板,并取代了内容块的内容,你使用一个<h1>标题,它也作为标题。

你在字符串中使用一个 Jinja for loop 来浏览消息列表中的每个消息,你使用一个<div>标签来包含消息的标题和内容,你将标题显示在<h3>标题中,内容显示在<p>标签中。

在您的flask_app目录中,您的虚拟环境已启用,请使用FLASK_APP环境变量告诉Flask关于该应用程序(在这种情况下,app.py):

1export FLASK_APP=app

然后将FLASK_ENV环境变量设置为development,以便在开发模式下运行应用程序并获取调试器的访问。 有关 Flask 调试器的更多信息,请参阅 如何处理 Flask 应用程序中的错误

1export FLASK_ENV=development

接下来,运行应用程序:

1flask run

当开发服务器运行时,请使用您的浏览器访问以下URL:

1http://127.0.0.1:5000/

您将在索引页面上显示的消息列表中看到消息:

Index Page

现在您已经设置了 Web 应用程序并显示了消息,您需要一种方式来允许用户将新消息添加到索引页面上。

步骤2 - 设置表格

在此步骤中,您将在应用程序中创建一个页面,允许用户通过 Web 表格将新消息添加到消息列表中。

让开发服务器运行,并打开一个新的终端窗口。

首先,打开app.py文件:

1nano app.py

将下列路径添加到文件的末尾:

1[label flask_app/app.py]
2# ...
3
4@app.route('/create/', methods=('GET', 'POST'))
5def create():
6    return render_template('create.html')

保存并关闭文件。

/create路径具有methods参数,附有('GET',POST)来接受GETPOST请求,而GETPOSTHTTP方法(https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)。默认情况下,只接受GET请求,这些请求用于获取数据,例如向服务器请求索引页面或关于页面。

在本示例中,您将使用GET请求请求创建页面。创建页面将有一个包含输入字段和提交按钮的网页表单。当用户填写网页表单并点击提交按钮时,将发送一个POST请求到创建路径。

Create()视图函数目前只做一件事:当它收到一个常规的GET请求时,将渲染名为create.html的模板.您现在将创建此模板,然后在下一步中编辑该函数来处理POST请求。

打开一个名为create.html的新模板文件:

1nano templates/create.html

添加以下代码:

 1[label flask_app/templates/create.html]
 2{% extends 'base.html' %}
 3
 4{% block content %}
 5    <h1>{% block title %} Add a New Message {% endblock %}</h1>
 6    <form method="post">
 7        <label for="title">Title</label>
 8        <br>
 9        <input type="text" name="title"
10               placeholder="Message title"
11               value="{{ request.form['title'] }}"></input>
12        <br>
13
14        <label for="content">Message Content</label>
15        <br>
16        <textarea name="content"
17                  placeholder="Message content"
18                  rows="15"
19                  cols="60"
20                  >{{ request.form['content'] }}</textarea>
21        <br>
22        <button type="submit">Submit</button>
23    </form>
24{% endblock %}

保存并关闭文件。

在此代码中,您将base.html模板扩展,并用作为页面标题的<h1>标题取代内容块,在<form>标签中,您将方法属性设置为发布,以便表单数据作为POST请求发送到服务器。

在表单中,你有一个名为标题的文本输入字段;这是你在应用程序上使用的名称来访问标题表单数据。你给了<input>标签的{{ request.form['title]] }}。这有助于恢复用户输入的数据,以便在事情发生错误时不会丢失。例如,如果用户忘记填写所需的内容文本区域,请求会发送到服务器,错误消息会作为响应返回,但标题中的数据不会丢失,因为它将保存在请求全球对象上,并且可以通过request.form[title]`访问。

在标题输入字段之后,您将添加一个名为内容的文本区域,其值为{ request.form['content'] }},原因与前面提到的原因相同。

最后,您在表单的末尾有一个提交按钮。

现在,随着开发服务器运行,使用您的浏览器导航到‘/create’路径:

1http://127.0.0.1:5000/create

您将看到添加新消息页面,其中包含消息标题的输入字段、消息内容的文本区域和提交按钮。

Add a new message

此表单将POST请求发送到您的Create()视图函数中,然而,该函数中尚无处理POST请求的代码,因此在填写表单并提交表单后不会发生任何情况。

步骤3 - 处理请求表格

在此步骤中,您将在应用程序侧处理表单请求。您将访问用户通过您在前一步创建的表单提交的表单数据,并将其添加到消息列表中。

打开app.py文件来编辑:

1nano app.py

首先,您将从 Flask 框架中导入以下内容:

  • 全球 request对象访问通过您在最后一步构建的HTML表格提交的入口请求数据。
  • url_for()函数生成URL。
  • flash()函数在处理请求时闪烁消息(通知用户一切顺利,或通知他们如果提交的数据不有效时出现问题)。

将这些导入添加到文件中的第一行:

1[label flask_app/app.py]
2from flask import Flask, render_template, request, url_for, flash, redirect
3
4# ...

这个秘密密密钥用于保护会话,使Flask能够记住从一个请求到另一个请求的信息,例如从新消息页到索引页。用户可以访问会话中存储的信息,但除非他们有秘密密密钥,否则无法更改它,因此您绝不能允许任何人访问您的秘密密密钥。

秘密密钥应该是一个长的随机字符串. 您可以使用os模块生成秘密密密钥,使用 os.urandom() 方法,该方法返回一个适合加密使用的随机字符串。

1python

在Python互动壳中,从标准库导入os模块,然后按以下方式调用os.urandom()方法:

1import os
2os.urandom(24).hex()

你会得到一个类似于以下的字符串:

1[secondary_label Output]
2
3'df0331cefc6c2b9a5d0208a726a5d1c0fd37324feba25506'

你可以使用你得到的字符串作为你的秘密密钥。

要设置秘密密钥,请通过app.config对象将SECRET_KEY配置添加到您的应用程序中。

 1[label flask_app/app.py]
 2
 3# ...
 4app = Flask(__name__)
 5app.config['SECRET_KEY'] = 'your secret key'
 6
 7messages = [{'title': 'Message One',
 8             'content': 'Message One Content'},
 9            {'title': 'Message Two',
10             'content': 'Message Two Content'}
11            ]
12# ...

接下来,更改创建()视图函数,看起来完全如下:

 1[label flask_app/app.py]
 2# ...
 3
 4@app.route('/create/', methods=('GET', 'POST'))
 5def create():
 6    if request.method == 'POST':
 7        title = request.form['title']
 8        content = request.form['content']
 9
10        if not title:
11            flash('Title is required!')
12        elif not content:
13            flash('Content is required!')
14        else:
15            messages.append({'title': title, 'content': content})
16            return redirect(url_for('index'))
17
18    return render_template('create.html')

如果声明中,您可以确保仅当请求是POST请求时,通过比较request.method ==POST`执行随后的代码。

然后,您将提交的标题和内容从request.form对象中提取,该对象允许您访问请求中的表单数据。如果标题未提供,则将满足如果不是标题的条件。在这种情况下,您会向用户显示信息,通知他们使用flash()函数使用标题。这将该信息添加到flashed messages列表中。您将后来在页面上显示这些信息作为base.html模板的一部分。同样,如果内容未提供,则将满足elif not content的条件。

如果邮件的标题和内容被正确提交,则使用messages.append({'title: title, 'content': content})来将新字典添加到messages列表中,使用用户提供的标题和内容。

保存并关闭文件。

现在,使用您的网页浏览器导航到创建路径:

1http://127.0.0.1:5000/create

填写表格以您选择的标题和一些内容. 一旦您提交表单,您将看到新消息列在索引页面上。

最后,你会显示闪烁的消息,并将新消息页面的链接添加到base.html模板中的导航栏中,以便轻松访问这个新页面。

1nano templates/base.html

通过在nav标签内的导航栏中添加一个新的<a>标签,然后直接在内容块上添加一个新的for循环,以显示导航栏下方的闪存消息。这些消息可在Flask提供的特殊get_flashed_messages()函数中使用。然后在每个消息中添加一个名为alert的类属性,并在<style>标签中给它一些CSS属性:

 1[label flask_app/templates/base.html]
 2<!DOCTYPE html>
 3<html lang="en">
 4<head>
 5    <meta charset="UTF-8">
 6    <title>{% block title %} {% endblock %} - FlaskApp</title>
 7    <style>
 8        .message {
 9            padding: 10px;
10            margin: 5px;
11            background-color: #f3f3f3
12        }
13        nav a {
14            color: #d64161;
15            font-size: 3em;
16            margin-left: 50px;
17            text-decoration: none;
18        }
19
20        .alert {
21            padding: 20px;
22            margin: 5px;
23            color: #970020;
24            background-color: #ffd5de;
25        }
26
27    </style>
28</head>
29<body>
30    <nav>
31        <a href="{{ url_for('index') }}">FlaskApp</a>
32        <a href="{{ url_for('create') }}">Create</a>
33        <a href="#">About</a>
34    </nav>
35    <hr>
36    <div class="content">
37        {% for message in get_flashed_messages() %}
38            <div class="alert">{{ message }}</div>
39        {% endfor %}
40        {% block content %} {% endblock %}
41    </div>
42</body>
43</html>

保存并关闭文件,然后在您的浏览器中重新加载 https://127.0.0.1:5000. 导航栏现在将有一个创建项目,链接到 /create 路线。

要查看闪存消息是如何工作的,请前往创建页面,然后单击提交按钮,而不填写两个字段。

No title no content flash message

回到索引页面,你会看到导航栏下方的闪存消息消失,即使它们显示为基础模板的一部分. 如果它们不是闪存消息,它们也会显示在索引页面上,因为它也继承了基础模板。

尝试以标题,但没有内容提交表单. 您将看到需要内容!消息。 在导航栏中点击 FlaskApp 链接返回索引页面,然后点击返回按钮返回创建页面。

您现在知道如何接收用户输入,如何验证它,以及如何将其添加到数据源中。

<$>[注] 注: 您添加到消息列表的消息将在服务器停止时消失,因为Python列表只存储在内存中,要永久保存您的消息,您需要使用SQLite等数据库。

结论

您创建了一个Flask应用程序,用户可以在索引页面上显示的消息列表中添加消息,您创建了一个Web表单,处理用户通过表单提交的数据,并将其添加到您的消息列表。

如果您想了解更多关于Flask的信息,请查看Flask系列中的其他教程(https://www.digitalocean.com/community/tutorial_series/how-to-create-web-sites-with-flask)。

Published At
Categories with 技术
comments powered by Disqus