WTForms是一個支持多個web框架的form組件,主要用於對用戶請求數據進行驗證。html
安裝:html5
pip3 install wtforms
python
一、用戶登陸web
具體代碼:flask
from flask import Flask,render_template,request,redirect from wtforms.fields import core from wtforms.fields import html5 from wtforms.fields import simple from wtforms import Form from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") class Myvalidators(object): '''自定義驗證規則''' def __init__(self,message): self.message = message def __call__(self, form, field): print(field.data,"用戶輸入的信息") if field.data == "haiyan": return None raise validators.ValidationError(self.message) class LoginForm(Form): '''Form''' name = simple.StringField( label="用戶名", widget=widgets.TextInput(), validators=[ Myvalidators(message="用戶名必須是haiyan"),#也能夠自定義正則 validators.DataRequired(message="用戶名不能爲空"), validators.Length(max=8,min=3,message="用戶名長度必須大於%(max)d且小於%(min)d") ], render_kw={"class":"form-control"} #設置屬性 ) pwd = simple.PasswordField( label="密碼", validators=[ validators.DataRequired(message="密碼不能爲空"), validators.Length(max=8,min=3,message="密碼長度必須大於%(max)d且小於%(min)d"), validators.Regexp(regex="\d+",message="密碼必須是數字"), ], widget=widgets.PasswordInput(), render_kw={"class":"form-control"} ) @app.route('/login',methods=["GET","POST"]) def login(): if request.method =="GET": form = LoginForm() return render_template("login.html",form=form) else: form = LoginForm(formdata=request.form) if form.validate(): print("用戶提交的數據用過格式驗證,值爲:%s"%form.data) return "登陸成功" else: print(form.errors,"錯誤信息") return render_template("login.html",form=form) if __name__ == '__main__': # app.__call__() app.run(debug=True)
login.html緩存
<body> <form action="" method="post" novalidate> <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="提交"> <!--用戶名:<input type="text">--> <!--密碼:<input type="password">--> <!--<input type="submit" value="提交">--> </form> </body>
二、用戶註冊session
from flask import Flask,render_template,redirect,request from wtforms import Form from wtforms.fields import core from wtforms.fields import html5 from wtforms.fields import simple from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") app.debug = True =======================simple=========================== class RegisterForm(Form): name = simple.StringField( label="用戶名", validators=[ validators.DataRequired() ], widget=widgets.TextInput(), render_kw={"class":"form-control"}, default="haiyan" ) pwd = simple.PasswordField( label="密碼", validators=[ validators.DataRequired(message="密碼不能爲空") ] ) pwd_confim = simple.PasswordField( label="重複密碼", validators=[ validators.DataRequired(message='重複密碼不能爲空.'), validators.EqualTo('pwd',message="兩次密碼不一致") ], widget=widgets.PasswordInput(), render_kw={'class': 'form-control'} ) ========================html5============================ email = html5.EmailField( #注意這裏用的是html5.EmailField label='郵箱', validators=[ validators.DataRequired(message='郵箱不能爲空.'), validators.Email(message='郵箱格式錯誤') ], widget=widgets.TextInput(input_type='email'), render_kw={'class': 'form-control'} ) ===================如下是用core來調用的======================= gender = core.RadioField( label="性別", choices=( (1,"男"), (1,"女"), ), coerce=int #限制是int類型的 ) city = core.SelectField( label="城市", choices=( ("bj","北京"), ("sh","上海"), ) ) hobby = core.SelectMultipleField( label='愛好', choices=( (1, '籃球'), (2, '足球'), ), coerce=int ) favor = core.SelectMultipleField( label="喜愛", choices=( (1, '籃球'), (2, '足球'), ), widget = widgets.ListWidget(prefix_label=False), option_widget = widgets.CheckboxInput(), coerce = int, default = [1, 2] ) def __init__(self,*args,**kwargs): #這裏的self是一個RegisterForm對象 '''重寫__init__方法''' super(RegisterForm,self).__init__(*args, **kwargs) #繼承父類的init方法 self.favor.choices =((1, '籃球'), (2, '足球'), (3, '羽毛球')) #吧RegisterForm這個類裏面的favor從新賦值 def validate_pwd_confim(self,field,): ''' 自定義pwd_config字段規則,例:與pwd字段是否一致 :param field: :return: ''' # 最開始初始化時,self.data中已經有全部的值 if field.data != self.data['pwd']: # raise validators.ValidationError("密碼不一致") # 繼續後續驗證 raise validators.StopValidation("密碼不一致") # 再也不繼續後續驗證 @app.route('/register',methods=["GET","POST"]) def register(): if request.method=="GET": form = RegisterForm(data={'gender': 1}) #默認是1, return render_template("register.html",form=form) else: form = RegisterForm(formdata=request.form) if form.validate(): #判斷是否驗證成功 print('用戶提交數據經過格式驗證,提交的值爲:', form.data) #全部的正確信息 else: print(form.errors) #全部的錯誤信息 return render_template('register.html', form=form) if __name__ == '__main__': app.run()
register.htmlapp
<body> <h1>用戶註冊</h1> <form method="post" novalidate style="padding:0 50px"> {% for item in form %} <p>{{item.label}}: {{item}} {{item.errors[0] }}</p> {% endfor %} <input type="submit" value="提交"> </form> </body>
三、meta框架
#!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Flask, render_template, request, redirect, session from wtforms import Form from wtforms.csrf.core import CSRF from wtforms.fields import core from wtforms.fields import html5 from wtforms.fields import simple from wtforms import validators from wtforms import widgets from hashlib import md5 app = Flask(__name__, template_folder='templates') app.debug = True class MyCSRF(CSRF): """ Generate a CSRF token based on the user's IP. I am probably not very secure, so don't use me. """ def setup_form(self, form): self.csrf_context = form.meta.csrf_context() self.csrf_secret = form.meta.csrf_secret return super(MyCSRF, self).setup_form(form) def generate_csrf_token(self, csrf_token): gid = self.csrf_secret + self.csrf_context token = md5(gid.encode('utf-8')).hexdigest() return token def validate_csrf_token(self, form, field): print(field.data, field.current_token) if field.data != field.current_token: raise ValueError('Invalid CSRF') class TestForm(Form): name = html5.EmailField(label='用戶名') pwd = simple.StringField(label='密碼') class Meta: # -- CSRF # 是否自動生成CSRF標籤 csrf = True # 生成CSRF標籤name csrf_field_name = 'csrf_token' # 自動生成標籤的值,加密用的csrf_secret csrf_secret = 'xxxxxx' # 自動生成標籤的值,加密用的csrf_context csrf_context = lambda x: request.url # 生成和比較csrf標籤 csrf_class = MyCSRF # -- i18n # 是否支持本地化 # locales = False locales = ('zh', 'en') # 是否對本地化進行緩存 cache_translations = True # 保存本地化緩存信息的字段 translations_cache = {} @app.route('/index/', methods=['GET', 'POST']) def index(): if request.method == 'GET': form = TestForm() else: form = TestForm(formdata=request.form) if form.validate(): print(form) return render_template('index.html', form=form) if __name__ == '__main__': app.run()
from flask import Flask,render_template,redirect,request from wtforms import Form from wtforms.fields import core from wtforms.fields import html5 from wtforms.fields import simple from wtforms import validators from wtforms import widgets app = Flask(__name__,template_folder="templates") app.debug = True
=======================simple=========================== class RegisterForm(Form): name = simple.StringField( label="用戶名", validators=[ validators.DataRequired() ], widget=widgets.TextInput(), render_kw={"class":"form-control"}, default="haiyan" ) pwd = simple.PasswordField( label="密碼", validators=[ validators.DataRequired(message="密碼不能爲空") ] ) pwd_confim = simple.PasswordField( label="重複密碼", validators=[ validators.DataRequired(message='重複密碼不能爲空.'), validators.EqualTo('pwd',message="兩次密碼不一致") ], widget=widgets.PasswordInput(), render_kw={'class': 'form-control'} )
========================html5============================ email = html5.EmailField( #注意這裏用的是html5.EmailField label='郵箱', validators=[ validators.DataRequired(message='郵箱不能爲空.'), validators.Email(message='郵箱格式錯誤') ], widget=widgets.TextInput(input_type='email'), render_kw={'class': 'form-control'} )
===================如下是用core來調用的======================= gender = core.RadioField( label="性別", choices=( (1,"男"), (1,"女"), ), coerce=int #限制是int類型的 ) city = core.SelectField( label="城市", choices=( ("bj","北京"), ("sh","上海"), ) ) hobby = core.SelectMultipleField( label='愛好', choices=( (1, '籃球'), (2, '足球'), ), coerce=int ) favor = core.SelectMultipleField( label="喜愛", choices=( (1, '籃球'), (2, '足球'), ), widget = widgets.ListWidget(prefix_label=False), option_widget = widgets.CheckboxInput(), coerce = int, default = [1, 2] ) def __init__(self,*args,**kwargs): #這裏的self是一個RegisterForm對象 '''重寫__init__方法''' super(RegisterForm,self).__init__(*args, **kwargs) #繼承父類的init方法 self.favor.choices =((1, '籃球'), (2, '足球'), (3, '羽毛球')) #吧RegisterForm這個類裏面的favor從新賦值 def validate_pwd_confim(self,field,): ''' 自定義pwd_config字段規則,例:與pwd字段是否一致 :param field: :return: ''' # 最開始初始化時,self.data中已經有全部的值 if field.data != self.data['pwd']: # raise validators.ValidationError("密碼不一致") # 繼續後續驗證 raise validators.StopValidation("密碼不一致") # 再也不繼續後續驗證 @app.route('/register',methods=["GET","POST"]) def register(): if request.method=="GET": form = RegisterForm(data={'gender': 1}) #默認是1, return render_template("register.html",form=form) else: form = RegisterForm(formdata=request.form) if form.validate(): #判斷是否驗證成功 print('用戶提交數據經過格式驗證,提交的值爲:', form.data) #全部的正確信息 else: print(form.errors) #全部的錯誤信息 return render_template('register.html', form=form) if __name__ == '__main__': app.run()