Flask笔记(5):表单

Flask有众多的扩展来简化集成各种常用的库和框架,比如Flask-Bootstrap集成了Bootstrap,Flask-WTF集成了WTForms。这篇要介绍的就是Flask-WTF。

 

安装和配置

安装很简单,使用pip:

pip install flask-wtf

Flask-WTF默认支持CSRF(跨站请求伪造)保护,只需要在程序中设置一个密钥。Flask-WTF使用这个密钥生成加密令牌,再用令牌验证表单中数据的真伪。(关于Flask项目的配置和初始化,后续文章会谈到)你可以使用app.config字典来存储配置变量:

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'

或是从系统环境变量中获取

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')

很多重要的信息,比如邮箱账户和密码都不能直接下载程序里,而要设置系统环境变量,设置方法如下(Windows CMD):

set SECRET_KEY=very very hard to guess string

后面的字符串不需要用任何符号括起来。

 

表单

每个表单都用一个继承自Form的类表示,每个字段都用一个对象表示,每个对象可以附加多个验证函数。常见的验证函数有Required()Length()Email()等。
一个登录表单示例:

from flask_wtf import Form # 导入Form
from wtforms import StringField, SubmitField, RadioField, PasswordField, BooleanField # 导入字段
from wtforms.validators import Required, Length, Email # 导入验证函数
class LoginForm(Form):
    email = StringField(u'邮箱', validators=[Required(message= u'邮箱不能为空'), Length(1, 64), Email(message= u'请输入有效的邮箱地址,比如:username@domain.com')])
    password = PasswordField(u'密码', validators=[Required(message= u'密码不能为空')])
    remember_me = BooleanField(u'记住我')
    submit = SubmitField(u'登录')
  • 在验证函数中传入出错时的提示信息,覆盖默认的英文错误提示。
  • WTForms支持的基本字段
  • WTForms支持的验证函数
 

渲染表单

表单有很多种渲染方式。
下面以一个撰写文章的表单为例。

 

默认的渲染方式

<form class="form" method="POST">
    {{ form.hidden_tag() }}
    {{ form.title.label }}{{ form.title() }}
    {{ form.body.label }}{{ form.body() }}
    {{ form.submit() }}
</form>

这种方式渲染出来的表单没有样式,而且很繁琐(当然,你也可以使用for循环来遍历字段)。

 

使用Flask-Bootstrap渲染

Flask-Bootstrap提供了一个模板(wtf.html),可以让你快速生成样式良好的表单。

{% import "bootstrap/wtf.html" as wtf %}
<form class="form" method="POST">
    {{ form.hidden_tag() }}
    {{ wtf.form_field(form.title) }}
    {{ wtf.form_field(form.body) }}
    {{ wtf.form_field(form.submit) }}
</form>

假如你不需要调整Boostrap的默认表单样式,只想要快速生成表单,那么Flask-Bootstrap还提供了一个强大的函数,只需要一行就可以快速生成表单):

{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
 

控制表单的样式

对于样式,可以通过给表单增加id或class来实现。比如这样:

{{ form.body.label }}{{ form.body(class="post-body") }} # 默认渲染
{{ wtf.form_field(form.body, class="post-body") }} # 使用Flask-Bootstrap渲染

也可以在表单类里传入参数,像这样:

body = TextAreaField(u'正文', validators=[Required(u'内容不能为空!')], render_kw={'rows': 20, 'placeholder': u'你有什么想法?'})

在表单字段里传入一个render_kw字典,将HTML的参数和值以键值对的形式写入字典。WTForms2.1及以上版本适用。

这里需要注意的是,Flask-Bootstrap会给表单添加class来控制样式,这时你再通过render_kw传入已经被定义过的参数会失败。所以,如果要使用render_kw传入class,得确保表单字段使用默认的渲染方式。

 

提交表单视图

这是一个添加文章的视图。

@main.route('/new/post', methods=['GET', 'POST'])
@login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
    post = Post(
    title = form.title.data,
    body = form.body.data)
    db.session.add(post)
    db.session.commit()
    return redirect(url_for('.post', id=post.id))
return render_template('edit/new_post.html', form=form)
 

常见问题索引

  1. 一个页面里有多个表单
  2. 文件及多文件上传
  3. 文本编辑器支持

 

撰写评论

电子邮件地址不会被公开,必填项已用 * 标出。