首页 > Python基础教程 >
-
带你认识 flask web 表单(2)
接收表单数据
点击提交按钮,浏览器将显示“Method Not Allowed”错误。为什么呢?这是因为之前的登录视图功能到目前为止只完成了一半的工作。它可以在网页上显示表单,但没有逻辑来处理用户提交的数据。Flask-WTF可以轻松完成这部分工作, 以下是视图函数的更新版本,它接受和验证用户提交的数据:
from flask import render_template, flash, redirect
'/login', methods=['GET', 'POST']) .route(
def login():
form = LoginForm()
if form.validate_on_submit():
flash('Login requested for user {}, remember_me={}'.format(
form.username.data, form.remember_me.data))
return redirect('/index')
return render_template('login.html', title='Sign In', form=form)
这个版本中的第一个新东西是路由装饰器中的methods
参数。它告诉Flask这个视图函数接受GET
和POST
请求,并覆盖了默认的GET
。HTTP协议规定对GET
请求需要返回信息给客户端(本例中是浏览器)。本应用的所有GET
请求都是如此。当浏览器向服务器提交表单数据时,通常会使用POST
请求(实际上用GET
请求也可以,但这不是推荐的做法)。之前的“Method Not Allowed”错误正是由于视图函数还未配置允许POST
请求。通过传入methods
参数,你就能告诉Flask哪些请求方法可以被接受。
form.validate_on_submit()
实例方法会执行form校验的工作。当浏览器发起GET
请求的时候,它返回False
,这样视图函数就会跳过if
块中的代码,直接转到视图函数的最后一句来渲染模板。
当用户在浏览器点击提交按钮后,浏览器会发送POST
请求。form.validate_on_submit()
就会获取到所有的数据,运行字段各自的验证器,全部通过之后就会返回True
,这表示数据有效。不过,一旦有任意一个字段未通过验证,这个实例方法就会返回False
,引发类似GET
请求那样的表单的渲染并返回给用户。稍后我会在添加代码以实现在验证失败的时候显示一条错误消息。
当form.validate_on_submit()
返回True
时,登录视图函数调用从Flask导入的两个新函数。 flash()
函数是向用户显示消息的有效途径。许多应用使用这个技术来让用户知道某个动作是否成功。我将使用这种机制作为临时解决方案,因为我没有基础架构来真正地登录用户。显示一条消息来确认应用已经收到登录认证凭据,我认为对当前来说已经足够了。
登录视图函数中使用的第二个新函数是redirect()
。这个函数指引浏览器自动重定向到它的参数所关联的URL。当前视图函数使用它将用户重定向到应用的主页。
当你调用flash()
函数后,Flask会存储这个消息,但是却不会奇迹般地直接出现在页面上。模板需要将消息渲染到基础模板中,才能让所有派生出来的模板都能显示出来。更新后的基础模板代码如下:
<html>
<head>
{% if title %}
<title>{{ title }} - microblog</title>
{% else %}
<title>microblog</title>
{% endif %}
</head>
<body>
<div>
Microblog:
<a href="/index">Home</a>
<a href="/login">Login</a>
</div>
<hr>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</body>
</html>
此处我用了with
结构在当前模板的上下文中来将get_flashed_messages()
的结果赋值给变量messages
。get_flashed_messages()
是Flask中的一个函数,它返回用flash()
注册过的消息列表。接下来的条件结构用来检查变量messages
是否包含元素,如果有,则在<ul>
元素中,为每条消息用<li>
元素来包裹渲染。这种渲染的样式结果看起来不会美观,之后会有主题讲到Web应用的样式。
闪现消息的一个有趣的属性是,一旦通过get_flashed_messages
函数请求了一次,它们就会从消息列表中移除,所以在调用flash()
函数后它们只会出现一次。
时机成熟,再次测试表单吧,将username和password字段留空并点击提交按钮来观察DataRequired
验证器是如何中断提交处理流程的。
完善字段验证
表单字段的验证器可防止无效数据被接收到应用中。应用处理无效表单输入的方式是重新显示表单,以便用户进行更正。
如果你尝试过提交无效的数据,相信你会注意到,虽然验证机制查无遗漏,却没有给出表单错误的具体线索。下一个任务是通过在验证失败的每个字段旁边添加有意义的错误消息来改善用户体验。
实际上,表单验证器已经生成了这些描述性错误消息,所缺少的不过是模板中的一些额外的逻辑来渲染它们。
这是给username和password字段添加了验证描述性错误消息渲染逻辑之后的登录模板:
{% extends "base.html" %}
{% block content %}
<h1>Sign In</h1>
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}<br>
{% for error in form.username.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}<br>
{% for error in form.password.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
<p>{{ form.submit() }}</p>
</form>
{% endblock %}
我做的唯一的改变是,在username和password字段之后添加for循环以便用红色字体来渲染验证器添加的错误信息。通常情况下,拥有验证器的字段都会用form.<field_name>.errors
来渲染错误信息。一个字段的验证错误信息结果是一个列表,因为字段可以附加多个验证器,并且多个验证器都可能会提供错误消息以显示给用户。
如果你尝试在未填写username和password字段的情况下提交表单,就可以看到显眼的红色错误信息了。