form组件校验源码
1.知识储备
1 form组件:写一个类继承Form,写字段 2 做数据校验(一直有用) 3 模板渲染(混合开发,前后端分离用不到) 4 校验数据:form=Myform(data=字典) 5 字段参数:error_messages,widget,required,max_length,min_length,label 6 错误信息:err=form.errors.get('__all__')#__all__是全局钩子抛出的错误 7 局部和全局钩子 -def clean_字段名(self): -校验通过返回该字段的数据部分 -校验失败抛出异常ValidationError -def clean(self) -校验通过返回cleaned_data -校验失败抛出异常ValidationError
2.源码笔记
1 读的入口是: form.is_valid()--->self.errors(BaseForm类)---》self.full_clean()(BaseForm类)--》 -self._clean_fields(局部数据校验)和self._clean_form(全局数据校验) 2 self._clean_fields(BaseForm类) #核心代码,在for循环里面做的事情 ''' 自己校验-->局部钩子 自己校验-->局部钩子 ... 全局钩子(最后,只能有一个全局钩子) ''' for name, field in self.fields.items(): try: # 字段自己的校验(最大值,最小值,是不是邮箱格式) #如果合法,放clean_data里,不合法抛异常ValidationError捕获异常 value = field.clean(value) #合法后,放到clean_data里 self.cleaned_data[name] = value #局部校验通过后才走这里,不通过不走 if hasattr(self, 'clean_%s' % name): # 反射判断有没有clean_字段名 value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value except ValidationError as e: self.add_error(name, e) 3 self._clean_form(BaseForm类) 全局钩子 try: cleaned_data = self.clean() # self.clean执行的是自己类的clean方法,没有clean方法再找父类 except ValidationError as e: self.add_error(None, e) else: if cleaned_data is not None: self.cleaned_data = cleaned_data
3.拓展
面向切面编程(AOP 全称Aspect Oriented Programming
)---现在 java spring里面的AOP 有名 ---
也叫做面向方法编程,是通过预编译方式和运行期动态代理的方式实现不修改源代码的情况下给程序动态统一添加功能的技术。
AOP技术利用一种称为“横切”的技术,剖解开封装对象的内部,将影响多个类的公共行为封装到一个可重用的模块中,并将其命名为Aspect切面。
AOP是实现分散关注的编程方法,将关注封装在切面中。如何分散关注呢?将需求功能从不相关的类中分离出来,同时使多个类共用一个行为,一旦行为发生变化,不必修改多个类,只修改行为即可。
利用AOP可以对业务逻辑各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发效率。
AOP的使用场景主要包括日志记录、性能统计、安全控制、事务处理、异常处理等。
面向对象编程(OOP 全称 Object Oriented Programming )
AOP与OOP有什么关系呢?
AOP和OOP是面向不同领域的两种思想,OOP面向对象编程主要是针对业务处理过程中的实体的属性和行为的抽象与封装,以获得更加清晰高效地逻辑单元。
AOP面向切面编程是针对业务处理过程中的切面进行提取,它所面对的是处理过程中某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。
AOP可以说是OOP的补充和完善,OOP引入封装、继承、多态等概念建立了一种对象层次结构,用来模拟公共行为的一个集合。
当需要为分散的对象引入公共行为的时候,OOP显得无能为力,也就是说,OOP允许定义从上到下的关系,但并不适合定义从左到右的关系。