一、wtforms源码流程
1、实例化流程分析
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
2、验证流程分析
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
二、自定义Form组件
#!usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask,render_template,request,Markup
app = Flask(__name__,template_folder="templates")
app.debug = True
# ==============通过这几个类就可以显示了-==============
#插件
class Widget(object):
pass
class InputText(Widget):
def __call__(self, *args, **kwargs):
return "<input type='text' name='name'>"
class TextArea(Widget):
def __call__(self, *args, **kwargs):
return Markup("<textarea name='email'></textarea>")
#Form
class BaseForm(object):
def __init__(self):
#获取当前所有的字段
_fields = {}
for name, field in self.__class__.__dict__.items():
if isinstance(field, Field): # 筛选出字段是name和emailDe
_fields[name] = field
self._fields = _fields
self.data = {}
# print(_fields) # {'name': 111, 'email': 222}
def validate(self,request_data):
#先找到所有的字段,在执行每一个字段的validate方法
flag = True
for name, field in self._fields.items():
input_val = request_data.get(name,"") #用户输入的值
result= field.validate(input_val) #每一个字段自己校验
print("???????????",input_val,result)
if not result:
flag = False
else:
self.data[name] = input_val
return flag
#字段
class Field(object):
'''所有类的基类'''
def __str__(self): #python中的静态字段通过类能找到,通过对象也能找到
return Markup(self.widget()) #self就是StringField,self
class StringField(Field): #每个字段打印的时候都要去执行__str__,所以选择放在基类里面,自己没有就调用父类的
widget = InputText()
def validate(self,val):
if val:
return True
class EmaliField(Field):
widget = TextArea()
reg = ".*@.*"
def validate(self,val):
import re
print(re.match(self.reg,val),"************")
if re.match(self.reg,val):
return True
# ===============使用===============
class LoginForm(BaseForm):
name = StringField()
email = EmaliField()
@app.route('/index', methods=["GET","POST"])
def index():
form = LoginForm()
ret = form.validate(request.form)
print("验证成功",ret)
print("验证成功的值",form.data)
# print(form.name)
# print(form.email)
return render_template("index.html",form=form)
if __name__ == '__main__':
app.run()