WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。
下载
pip3 install wtforms
下面以一个登录和注册的示例来说明
登录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from wtforms.fields import simple from wtforms.fields import core from wtforms.fields import html5 from wtforms import widgets from wtforms import validators from wtforms import Form from .dbpool import POOL class LoginForm(Form): #首先执行后得到的结果是UnboundField()对象 name=simple.StringField( label='用户名', validators=[ validators.DataRequired(message='用户名不能为空'), ], widget=widgets.TextInput(), render_kw={'class': 'form-control'} ) pwd=simple.StringField( label='密码', validators=[ validators.DataRequired(message='密码不能为空'), ], widget=widgets.TextInput(), render_kw={'class': 'form-control'} )
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@user.route('/login',methods=['GET','POST']) def login(): if request.method=='GET': form=LoginForm() print(form) return render_template('login.html',form=form) else: form=LoginForm(request.form) if form.validate(): #数据库连接池创建链接 conn=POOL.connection() cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) sql='select * from userinfo where username=%s and pwd=%s ' print(form.data) username=form.data.get('name') pwd=form.data.get('pwd') cursor.execute(sql,[username,pwd]) user=cursor.fetchone() cursor.close() conn.close() if user: session['user']=user login_log.send() return render_template('index.html',user=user) return render_template('login.html',form=form,msg='用户名或密码错误') return render_template('login.html',form=form,)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <h1>用户登录</h1> <form method="post"> <p>{{ form.name.label }}{{ form.name }}{{ form.name.errors[0] }}</p> <p>{{ form.pwd.label }}{{ form.pwd }}{{ form.pwd.errors[0] }}</p> <input type="submit" value="提交"> {{ msg }} </form> </body> </html>
注册:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class RegisterForm(Form): name=simple.StringField( label='用户名', validators=[ validators.DataRequired('用户名不能为空'), validators.Length(max=8,min=2,message='用户名长度在%(min)d-%(max)d之间') ], widget=widgets.TextInput(), render_kw={'class': 'form-control'}, ) pwd=simple.StringField( label='密码', validators=[ validators.DataRequired(message='密码不能为空'), validators.Length(max=8,min=5,message='密码长度必须在%(min)d-%(max)d之间'), # validators.Regexp("^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[$@$!%*?&])[A-Za-zd$@$!%*?&]{8,}", # message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符'), ], widget=widgets.TextInput(), render_kw={'class': 'form-control'} ) pwd_confirm=simple.StringField( label='请再次输入密码', validators=[ validators.DataRequired(message='不能为空'), validators.EqualTo('pwd',message='两次输入的密码不一致') ], widget=widgets.TextInput(), render_kw={'class': 'form-control'} ) email=html5.EmailField( label='邮箱', validators=[ validators.DataRequired(message='邮箱不能为空'), validators.Email(message='邮箱格式不正确') ], widget=widgets.TextInput(), render_kw={"class":"form-control"} ) gender=core.RadioField( choices=( (1,'男'), (2,'女') ), coerce=int ) city=core.SelectField( choices=( ('km','昆明'), ('bj','北京'), ('cd','成都') ) ) hobby=core.SelectMultipleField( choices='', widget=widgets.ListWidget(prefix_label=False), option_widget=widgets.CheckboxInput(), coerce = int, default = [1, 2] ) def __init__(self,*args,**kwargs): super(RegisterForm, self).__init__(*args,**kwargs) self.hobby.choices=((1, '篮球'), (2, '足球'), (3, '羽毛球')) def validate_pwd_confirm(self,field): if field.data != self.data['pwd']: # raise validators.ValidationError("密码不一致")#继续后续验证 raise validators.StopValidation("密码不一致") #不再继续后续验证 def validate_name(self,field): conn=POOL.connection() cursor=conn.cursor() sql='select * from userinfo where username=%s' cursor.execute(sql,[field.data]) user=cursor.fetchone() if user: raise validators.StopValidation("该用户名已经被注册")
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@user.route('/regist',methods=['GET','POST']) def register(): if request.method=='GET': form=RegisterForm() return render_template('register.html',form=form) else: form=RegisterForm(request.form) if form.validate(): print(form.data) name=form.data.get('name') pwd=form.data.get('pwd') email=form.data.get('email') gender=form.data.get('gender') city=form.data.get('city') hobbys=form.data.get('hobby') conn=POOL.connection() cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) sql="insert into userinfo(username,pwd,email,gender,city)VALUES(%s,%s,%s,%s,%s)" cursor.execute(sql,[name,pwd,email,gender,city]) conn.commit() cursor.close() conn.close() return redirect('/login') return render_template('register.html', form=form)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form method="post"> {% for foo in form %} <p>{{foo.label }} {{foo}}{{ foo.errors[0] }}</p> {% endfor %} <input type="submit"> </form> </body> </html>