自定义form
一:form组件分为三类设计思想
设计思想:
插件
字段
Form
流程:
PS:按照结果反推流程
1,按照内置的form组件,首先会先继承Form,并且静态字段是继承Charfield类
class UserForm(Form): name=Charfield(errormsg={'required':'用户名不能为空'},widget=Textinput()) pwd=Emialfield(errormsg={'required':'密码不能为空'})
2,定义Form组件,让UserForm继承
要实现的功能:
1):找到userform的静态字段 PS:通过userform的__dict__方式.
2):找到静态字段后,要获取字段里面的结构 PS:字段继承哪个类,显示方式,客户填入的数据
3):判断客户输入的数据符合要求 字段格式的要求 PS:比如Charfield()的格式 比如 空字符,有正则匹配的
4):校验数据,并把所有的内容放入 cleaned_data里面 PS:还要注意是否有钩子函数,如果有钩子函数,那么数据一定要先通过钩子函数验证过才行.
5):如果数据错误,需要把错误信息放到error表中
6):最后字段在html页面的显示. 通过__iter__方法,把对象变成迭代器,一一生成, PS:这里就需要在另外写不同的类创建不同的html格式
总结:
Form类,是整个组件的中枢,他负责调动整个组件需求,除了自己的主要功能,别的零散需求则分配给下面的 字段和组件做
字段(Charfield)负责每个字段的显示
插件field则分配html页面的显示功能
3,上简单代码
class Textinput(object): def __str__(self): return "12" class Field(object): def __init__(self, required=None, invalid=None, errormsg=None,widget=None): self.msg = None self.errormsg = errormsg self.widget=widget if not self.widget: self.widget=Textinput() else: self.widget=widget def __str__(self): return str(self.widget) #这里一定要加上str class Emialfield(Field): def valid(self, val): if self.errormsg: for msg in self.errormsg: if msg == 'required': if not val: self.msg = self.errormsg['required'] raise Exception(self.msg) return val class Charfield(Field): def valid(self,val): # if self.required: # if self.errormsg: # if not val: #这里面可以进行 # self.errormsg=self.errormsg[self.required] # raise Exception(self.errormsg) # if self.errormsg: for msg in self.errormsg: if msg=='required': if not val: self.msg=self.errormsg['required'] raise Exception(self.msg) return val import copy class Form(object): def __init__(self,data): self.data=data self.field_dct=copy.deepcopy(self.__class__.field_dct) self.cleaned_data={} self.errmsg={} def __new__(cls, *args, **kwargs): dct={} for key,field in cls.__dict__.items(): if isinstance(field,Field): #找到所有的静态字段 dct[key]=field cls.field_dct=dct return super().__new__(cls) def is_valid(self): for key,field in self.field_dct.items(): try: value=field.valid(self.data.get(key,None)) self.cleaned_data[key]=value except Exception as e: self.errmsg[key]=str(e) return len(self.errmsg)==0 def __iter__(self): return iter(self.field_dct.values()) class UserForm(Form): name=Charfield(errormsg={'required':'用户名不能为空'},widget=Textinput()) pwd=Emialfield(errormsg={'required':'密码不能为空'}) obj=UserForm(data={'name':'alex','pwd':123}) if obj.is_valid(): print(obj.cleaned_data) else: print(obj.errmsg) for i in obj: print(i)