如何在Python Flask中使用表单

413 阅读4分钟

允许用户向你的网络应用提交数据是一个普遍的需求。无论你使用的是什么Web框架或解决方案,HTML表单都是通常用来收集和提交来自终端用户的数据给Web应用程序的方法。在本教程中,我们将看看如何让表单在Flask中工作,如何在Flask中获得表单数据,以及在使用Flask时如何访问各种表单字段。


在模板中添加一个表单

在页面模板中,让我们添加一些基本的标记,勾勒出一个表单。这个表单有一个URL的输入字段,一个短代码的输入字段,两个描述这些输入的标签,以及一个提交输入。

flask-tutorial/templates/home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Make A Short URL</title>
</head>
<body>
<h1>Make A Short URL</h1>
<form action="shortenurl">
    <label for="url">Enter URL</label>
    <input type="url" name="url" value="" required>
    <label for="shortcode">Enter Name</label>
    <input type="text" name="shortcode" value="" required>
    <input type="submit" value="Submit">
</form>

</body>
</html>

Flask HTML Form


提交表单数据

每个表单都有一个动作属性,指定表单提交到哪个URL。为了处理这个问题,我们需要在app.py中设置正确的路由。让我们修改app.py文件以反映这一点。同时,我们可以在项目中添加一个新的文件,命名为shortenurl.html,因为那是将被渲染的模板。

flask-tutorial/app.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/shortenurl')
def shortenurl():
    return render_template('shortenurl.html')

add template action flask file

在shortenurl.html文件中,我们可以添加一些基本的标记,让用户知道他们目前在什么页面上。

flask-tutorial/templates/shortenurl.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Here Is Your URL!</title>
</head>
<body>
<h1>Here Is Your URL!</h1>
</body>
</html>

如何访问请求数据

与HTML表单相关的数据是在HTTP请求中进行的。为了在Flask中访问表单请求数据,我们可以导入request并使用request.args

flask-tutorial/app.py

from flask import Flask, render_template, request

app = Flask(__name__)


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/shortenurl')
def shortenurl():
    return render_template('shortenurl.html', shortcode=request.args['shortcode'])

上面的代码使用request来获取中包含的数据,该数据存在于home.html中。现在,为了在表单提交后在另一个页面上显示这些数据,我们只需在Jinja模板中添加插值,我们在flask页面模板教程中探讨过。

flask-tutorial/templates/shortenurl.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Here Is Your URL!</title>
</head>
<body>
<h1>Here Is Your URL!</h1>
<h2>{{ shortcode }}</h2>
</body>
</html>

现在我们可以在表单中添加一些数据,然后点击提交。

add data to flask form

一旦点击,目标页面模板就会显示输入到短码输入栏的值。

after form submit flask


如何发出一个POST请求

到目前为止,代码中的管道已经到位,可以在Flask中实现基本的表单提交工作。它使用的是GET请求,这对Web表单来说不是很好。相反,我们应该让表单使用POST请求。要做到这一点,我们可以对表单和路由做一些调整。

指定表单动作

为了表明表单应该使用POST请求,我们可以在表单标签的开头添加method=post。

flask-tutorial/templates/home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Make A Short URL</title>
</head>
<body>
<h1>Make A Short URL</h1>
<form action="shortenurl" method="post">
    <label for="url">Enter URL</label>
    <input type="url" name="url" value="" required>
    <label for="shortcode">Enter Name</label>
    <input type="text" name="shortcode" value="" required>
    <input type="submit" value="Submit">
</form>

</body>
</html>

接下来,我们需要在app.py的路由中修复请求类型。如果你试图在Flask中提交一个指定为POST请求的表单,而app.py不能支持,你会得到一个错误,比如。"Method Not Allowed The method is not allowed for the requested URL"。为了使路由支持POST请求,可以使用下面的高亮代码。

flask-tutorial/app.py

from flask import Flask, render_template, request

app = Flask(__name__)


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/shortenurl', methods=['GET', 'POST'])
def shortenurl():
    return render_template('shortenurl.html', shortcode=request.args['shortcode'])

request.args vs request.form

现在提交表单会产生一个错误,这并不理想。

werkzeug.exceptions.BadRequestKeyError

werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'shortcode'

为了解决这个问题,我们可以在app.py中使用require.form而不是require.args

from flask import Flask, render_template, request

app = Flask(__name__)


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/shortenurl', methods=['GET', 'POST'])
def shortenurl():
    return render_template('shortenurl.html', shortcode=request.form['shortcode'])

此时,POST请求是成功的,数据显示在屏幕上,而且在网络浏览器的URL中没有包含难看的变量。

flask form post request

检测请求方法

一个单一的路由可能支持一个以上的请求类型。事实上,我们上面的代码让/shortenurl路由同时支持GET和POST请求。在这样的情况下,一个常见的模式是使用Python if语句来决定如何处理请求。下面对代码的更新是检查请求方法是否是POST类型的。如果是,那么 shortenurl.html 页面模板就会被渲染,同时将其中一个输入字段的数据传递给模板。如果是GET请求,会返回一个简单的字符串,让用户知道是GET请求。如果有任何其他请求,如PUT、PATCH或DELETE,那么我们会让用户知道这个特定的路由不支持这些请求方法。

flask-tutorial/app.py

from flask import Flask, render_template, request

app = Flask(__name__)


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/shortenurl', methods=['GET', 'POST'])
def shortenurl():
    if request.method == 'POST':
        return render_template('shortenurl.html', shortcode=request.form['shortcode'])
    elif request.method == 'GET':
        return 'A GET request was made'
    else:
        return 'Not a valid request method for this route'