Flask系列课程16:进阶表单处理和验证
一、Flask-使用WTF表单库
通常需要使用Flask-WTF库来处理Flask中的表单。
在Flask-WTF中,每个Web表格都应该通过创建一个类来实现,它继承自FlaskForm。该类定义了文本字段StringField等表单的字段类型。、EmailField等电子邮件字段。另外,我们可以指定这些字段的验证函数,以确保用户输入的数据是合法的。
假定在用户注册场景中,我们需要用户提供用户名、电子邮件地址和密码。使用Flask-WTF构建表格的例子代码如下:
from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField from wtforms.validators import DataRequired, Email, Length class RegistrationForm(FlaskForm): username = StringField('用户名', validators=[DataRequired()]) email = StringField('邮箱', validators=[DataRequired(), Email()]) password = PasswordField('密码', validators=[DataRequired(), Length(min=6)]) submit = SubmitField('注册')
表格模板渲染和数据验证
在模板文件中渲染这些表单字段是构建Flask表单的下一步。Flask-WTF与Jinja2模板引擎紧密结合,可将表单字段直观地渲染成HTML代码。当FlaskForm对象用于模板时,表单渲染和错误信息显示都很容易实现。
在大多数情况下,我们会在Jinja2模板中使用宏观模板(macro)重复使用模板代码,减少重复工作。然而,在下面的例子中,我们将直接在模板中编写字段,以便显示清楚。
下面是HTML模板代码的基本用户注册表,演示如何在模板中渲染FlaskForm的字段:
<form method="post" action="{{ url_for('register') }}"> {{ form.hidden_tag() }} <p> {{ form.username.label }}
{{ form.username(size=20) }} {% for error in form.username.errors %} <span style="color: red;">{{ error }}</span> {% endfor %} </p> <p> {{ form.email.label }}
{{ form.email(size=20) }} {% for error in form.email.errors %} <span style="color: red;">{{ error }}</span> {% endfor %} </p> <p> {{ form.password.label }}
{{ form.password(size=20) }} {% for error in form.password.errors %} <span style="color: red;">{{ error }}</span> {% endfor %} </p> <p>{{ form.submit() }}</p> </form>
处理表提交给用户反馈。
提交表格后,Flask视图函数需要处理这些数据并给予用户反馈。Flask-validate_WTF提供的on_submit()方法可以检查是否是POST请求,并进一步调用表单类中的验证函数。如果所有字段的数据都被验证,数据处理的业务逻辑就可以实现。
当表格处理完成后,需要给予用户适当的反馈。举例来说,如果用户注册成功,可以重新定向登录页面,并且使用Flask内置的flash()函数来显示一个成功的信息。否则,用户需要在表格页面上看到相应的错误信息,并且可以重新填写。
以下是处理用户注册的视图函数示例代码:
from flask import render_template, redirect, url_for, flash from app import app from app.forms import RegistrationForm @app.route('/register', methods=['GET', 'POST']) def register(): form = RegistrationForm() if form.validate_on_submit(): # 在此添加处理注册逻辑的代码 flash(‘注册成功!请登录。')请登录。 return redirect(url_for('login')) return render_template('register.html', form=form)
自定义验证器的使用
在某些情况下,预置验证器可能无法满足需求,我们可能需要进行一些特定的数据验证。例如,在用户注册时,我们需要确保用户名称和电子邮件地址不会与现有用户发生冲突。此时,WTForms的验证能力可以通过定制验证函数来扩展。
在相应字段的validators列表中,定制验证器通常作为表单类的方法来定义。WTForms会自动调用这些方法,并在验证失败时抛出ValidationError。
举例来说,下面的代码显示了如何定义用户名字段的自定义验证器,以确保用户名是唯一的:
from wtforms import ValidationError class RegistrationForm(FlaskForm): # ... 以前的字段定义 def validate_username(self, field): if User.query.filter_by(username=field.data).first(): raise ValidationError(‘用户名已经被占用,请使用其它用户名。')
表格样式和布局五、表格样式
除了保证表单的功能性外,表单的视觉效果也同样重要,以提高用户体验。美观直观的表单布局可以提高用户的填写效率和满意度。我们可以利用Bootstrap等前端框架,在Flask-WTF中快速实现响应式和美观的表单风格。
Flask-Bootstrap是Flask的扩展,集成了Bootstrap框架。它提供了一套简单的Jinja2宏来渲染表格,同时也支持定制风格类别。通过Flask-Bootstrap,能大大简化表格布局设计工作,并能保持用户界面一致。
下面是一个使用Flask-Bootstrap改进用户注册表格样式和布局的例子:
{% extends "bootstrap/base.html" %} {% block content %} <div class="container"> <h1>用户注册</h1> <form method="post" action="{{ url_for('register') }}"> {{ form.hidden_tag() }} {{ wtf.quick_form(form) }} </form> </div> {% endblock %}
继承bootstrap/上述代码。base.在content块中使用html模板.quick_form宏快速生成表格。通过这种方式,用户注册表格将具有Bootstrap定义的风格,使整个注册页面看上去更专业、更舒适。