Flask系列教程(29)——Flask-WTF表单

Flask-WTF
如果想深入学习Flask,可以观看这套免费Flask教学视频:零基础:Flask入门到项目实战

Flask-WTF是简化了WTForms操作的一个第三方库。WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板。当然还包括一些其他的功能:CSRF保护,文件上传等。安装Flask-WTF默认也会安装WTForms,因此使用以下命令来安装Flask-WTF:

pip install flask-wtf
1
表单验证:
安装完Flask-WTF后。来看下第一个功能,就是用表单来做数据验证,现在有一个forms.py文件,然后在里面创建一个RegistForm的注册验证表单:

class RegistForm(Form):
name = StringField(validators=[length(min=4,max=25)])
email = StringField(validators=[email()])
password = StringField(validators=[DataRequired(),length(min=6,max=10),EqualTo(‘confirm’)])
confirm = StringField()
1
2
3
4
5
在这个里面指定了需要上传的参数,并且指定了验证器,比如name的长度应该在4-25之间。email必须要满足邮箱的格式。password长度必须在6-10之间,并且应该和confirm相等才能通过验证。

写完表单后,接下来就是regist.html文件:

用户名:
邮箱:
密码:
确认密码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 再来看视图函数regist:

@app.route(’/regist/’,methods=[‘POST’,‘GET’])
def regist():
form = RegistForm(request.form)
if request.method == ‘POST’ and form.validate():
user = User(name=form.name.data,email=form.email.data,password=form.password.data)
db.session.add(user)
db.session.commit()
return u’注册成功!’
return render_template(‘regist.html’)
1
2
3
4
5
6
7
8
9
RegistForm传递的是request.form进去进行初始化,并且判断form.validate会返回用户提交的数据是否满足表单的验证。

渲染模板:
form还可以渲染模板,让你少写了一丢丢的代码,比如重写以上例子,RegistForm表单代码如下:

class RegistForm(Form):
name = StringField(u’用户名:’,validators=[length(min=4,max=25)])
email = StringField(u’邮箱:‘validators=[email()])
password = StringField(u’密码:’,validators=[DataRequired(),length(min=6,max=10),EqualTo(‘confirm’)])
confirm = StringField(u’确认密码:’)
1
2
3
4
5
以上增加了第一个位置参数,用来在html文件中,做标签提示作用。

在app中的视图函数中,修改为如下:

@app.route(’/regist/’,methods=[‘POST’,‘GET’])
def regist():
form = RegistForm(request.form)
if request.method == ‘POST’ and form.validate():
user = User(name=form.name.data,email=form.email.data,password=form.password.data)
db.session.add(user)
db.session.commit()
return u’注册成功!’
return render_template(‘regist.html’,form=form)
1
2
3
4
5
6
7
8
9
以上唯一的不同是在渲染模板的时候传入了form表单参数进去,这样在模板中就可以使用表单form变量了。

接下来看下regist.html文件:

{{ form.name.label }}{{ form.name() }}
{{ form.email.label }}{{ form.email() }}
{{ form.password.label }}{{ form.password() }}
{{ form.confirm.label }}{{ form.confirm() }}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Field常用参数: 在使用Field的时候,经常需要传递一些参数进去,以下将对一些常用的参数进行解释:

label(第一个参数):Field的label的文本。
validators:验证器。
id:Field的id属性,默认不写为该属性名。
default:默认值。
widget:指定的html控件。
常用Field:
BooleanField:布尔类型的Field,渲染出去是checkbox。
FileField:文件上传Field。

forms.py

from flask_wtf.file import FileField,FileAllowed,FileRequired
class UploadForm(FlaskForm):
avatar = FileField(u’头像:’,validators=[FileRequired(),FileAllowed([])])

app.py

@app.route(’/profile/’,methods=(‘POST’,‘GET’))
def profile():
form = ProfileForm()
if form.validate_on_submit():
filename = secure_filename(form.avatar.data.filename)
form.avatar.data.save(os.path.join(app.config[‘UPLOAD_FOLDER’],filename))
return u’上传成功’

return render_template('profile.html',form=form)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FloatField:浮点数类型的Field,但是渲染出去的时候是text的input。

IntegerField:整形的Field。同FloatField。

RadioField:radio类型的input。表单例子如下:

form.py

class RegistrationForm(FlaskForm):
gender = wtforms.RadioField(u’性别:’,validators=[DataRequired()])
1
2
3
模板文件代码如下:

{{ form.gender.label }} {% for gender in form.gender %} {{ gender.label }} {{ gender }} {% endfor %} 1 2 3 4 5 6 7 8 9 10 11 app.py文件的代码如下,给gender添加了choices:

@app.route(’/register/’,methods=[‘POST’,‘GET’])
def register():
form = RegistrationForm()
form.gender.choices = [(‘1’,u’男’),(‘2’,u’女’)]
if form.validate_on_submit():
return u’success’

return render_template('register.html',form=form)

1
2
3
4
5
6
7
8
SelectField:类似于RadioField。看以下示例:

forms.py

class ProfileForm(FlaskForm):
language = wtforms.SelectField(‘Programming Language’,choices=[(‘cpp’,‘C++’),(‘py’,‘python’),(‘text’,‘Plain Text’)],validators=[DataRequired()])
1
2
3
再来看app.py文件:

@app.route(’/profile/’,methods=(‘POST’,‘GET’))
def profile():
form = ProfileForm()
if form.validate_on_submit():
print form.language.data
return u’上传成功’
return render_template(‘profile.html’,form=form)
1
2
3
4
5
6
7
模板文件为:

{{ form.csrf_token }} {{ form.language.label }} {{ form.language() }} 1 2 3 4 5 6 StringField:渲染到模板中的类型为,并且是最基本的文本验证。

PasswordField:渲染出来的是一个password的input标签。

TextAreaField:渲染出来的是一个textarea。

常用的验证器:
数据发送过来,经过表单验证,因此需要验证器来进行验证,以下对一些常用的内置验证器进行讲解:

Email:验证上传的数据是否为邮箱。
EqualTo:验证上传的数据是否和另外一个字段相等,常用的就是密码和确认密码两个字段是否相等。
InputRequired:原始数据的需要验证。如果不是特殊情况,应该使用InputRequired。
Length:长度限制,有min和max两个值进行限制。
NumberRange:数字的区间,有min和max两个值限制,如果处在这两个数字之间则满足。
Regexp:自定义正则表达式。
URL:必须要是URL的形式。
UUID:验证UUID。
自定义验证字段:
使用validate_fieldname(self,field)可以对某个字段进行更加详细的验证,如下:

class ProfileForm(FlaskForm):
name = wtforms.StringField(‘name’,[validators.InputRequired()])
def validate_name(self,field):
if len(field.data) > 5:
raise wtforms.ValidationError(u’超过5个字符’)
1
2
3
4
5
CSRF保护:
在flask的表单中,默认是开启了csrf保护功能的,如果你想关闭表单的csrf保护,可以在初始化表单的时候传递csrf_enabled=False进去来关闭csrf保护。如果你想关闭这种默认的行为。如果你想在没有表单存在的请求视图函数中也添加csrf保护,可以开启全局的csrf保护功能:

csrf = CsrfProtect()
csrf.init_app(app)
1
2
或者是针对某一个视图函数,使用csrf.protect装饰器来开启csrf保护功能。并且如果已经开启了全局的csrf保护,想要关闭某个视图函数的csrf保护功能,可以使用csrf.exempt装饰器来取消本视图函数的保护功能。

AJAX的CSRF保护:
在AJAX中要使用csrf保护,则必须手动的添加X-CSRFToken到Header中。但是CSRF从哪里来,还是需要通过模板给渲染,而Flask比较推荐的方式是在meta标签中渲染csrf,如下:

1 如果要发送AJAX请求,则在发送之前要添加CSRF,代码如下(使用了jQuery):

var csrftoken = $(‘meta[name=csrf-token]’).attr(‘content’)
KaTeX parse error: Expected '}', got 'EOF' at end of input: …|OPTIONS|TRACE)/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader(“X-CSRFToken”, csrftoken)
}
}
});
1
2
3
4
5
6
7
8
如果想深入学习Flask,可以观看这套免费Flask教学视频:零基础:Flask入门到项目实战

作者:南窗客斯黄
来源:CSDN
原文:https://blog.csdn.net/nunchakushuang/article/details/80555277
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值