一、查看is_valid方法,返回self.is_bound和非self.errorside
def is_valid(self): """ Returns True if the form has no errors. Otherwise, False. If errors are being ignored, returns False. """ return self.is_bound and not self.errors
二、查看self.is_bound方法,能够看到data或者files只要有一个不为空,即为真post
self.is_bound = data is not None or files is not None
三、查看self.errors方法,能够看到判断self._errors若是为None,就执行full_clean()方法,(经过查看self._errors能够看到默认就是None,self._errors = None)ui
@property #装饰器将方法变成属性 def errors(self): "Returns an ErrorDict for the data provided for the form" if self._errors is None: self.full_clean() return self._errors
四、查看self.full_clean方法this
执行了self._clean_fields、self._clean_form和self._post_clean三个方法,这3个方法都执行完成后,full_clean方法就执行完成了。spa
def full_clean(self): """ Cleans all of self.data and populates self._errors and self.cleaned_data. """ self._errors = ErrorDict() #存放错误信息的字典,ErrorDict继承了dict if not self.is_bound: # Stop further processing. return self.cleaned_data = {} #存放通过校验的字典数据 # If the form is permitted to be empty, and none of the form data has # changed from the initial data, short circuit any validation. if self.empty_permitted and not self.has_changed(): return self._clean_fields() self._clean_form() self._post_clean()
五、查看self._clean_fields方法插件
def _clean_fields(self): for name, field in self.fields.items(): #将字典中的全部值都循环出来 if field.disabled: value = self.get_initial_for_field(field, name) #拿到默认值 else: value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) #拿到插件中定义的值 try: if isinstance(field, FileField): initial = self.get_initial_for_field(field, name) value = field.clean(value, initial) else: #执行字段中的clean方法(内置校验器的)和自定义校验器的校验,若是有错误就执行下面的add_error方法 value = field.clean(value) #若是内置校验器和自定义检验器都经过后就将该字段添加到cleaned_data字典中 self.cleaned_data[name] = value 若是没有错误,经过反向判断当前form里是否有定义的局部钩子,若是有就加括号执行这个局部钩子的方法,若是错误就执行下面的add_error方法,这里就是源码预留的局部钩子的定义方法,命名为clean_字段名称 if hasattr(self, 'clean_%s' % name): value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value #局部钩子校验经过后将数据保存到cleaned_data字典中,没有经过校验就抛出异常 except ValidationError as e: self.add_error(name, e)
六、查看self._clean_form方法code
内置校验器、自定义校验器、局部钩子都执行校验经过后,再执行self._clean_form方法中的self.clean方法orm
def _clean_form(self): try: cleaned_data = self.clean() except ValidationError as e: self.add_error(None, e) else: if cleaned_data is not None: self.cleaned_data = cleaned_data
七、查看self.clean方法blog
这里就是源码预留的全局钩子的定义方法,若是定义了全局钩子并经过校验,就返回全部数据继承
def clean(self): """ Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named '__all__'. """ return self.cleaned_data
八、都执行完成后,将错误信息保存在第4步中的self._errors = ErrorDict()这个错误字典中,若是没有错误信息,那么 self._errors = ErrorDict()这个错误字典就是空的。
第3步中的self.full_clean()就执行完成了,并返回return self._errors字典
第1步中的is_valid()就执行完了,若是没有错误信息,return self.is_bound and not self.errors就返回True,不然就返回False
执行顺序: