Django13-ModelForm中的is_valid及局部钩子、全局钩子源码解析
1、查看is_valid方法,返回self.is_bound和非self.errors
def is_valid(self):"""Returns True if the form has no errors. Otherwise, False. If errors arebeing ignored, returns False."""return self.is_bound and not self.errors2、查看self.is_bound方法,可以看到data或者files只要有一個不為空,即為真
self.is_bound = data is not None or files is not None3、查看self.errors方法,可以看到判斷self._errors如果為None,就執行full_clean()方法,(通過查看self._errors可以看到默認就是None,self._errors = None)
@property #裝飾器將方法變成屬性def errors(self):"Returns an ErrorDict for the data provided for the form"if self._errors is None:self.full_clean()return self._errors4、查看self.full_clean方法
執行了self._clean_fields、self._clean_form和self._post_clean三個方法,這3個方法都執行完成后,full_clean方法就執行完成了。
def full_clean(self):"""Cleans all of self.data and populates self._errors andself.cleaned_data."""self._errors = ErrorDict() #存放錯誤信息的字典,ErrorDict繼承了dictif not self.is_bound: # Stop further processing.returnself.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():returnself._clean_fields()self._clean_form()self._post_clean()5、查看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)6、查看self._clean_form方法
內置校驗器、自定義校驗器、局部鉤子都執行校驗通過后,再執行self._clean_form方法中的self.clean方法
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_data7、查看self.clean方法
這里就是源碼預留的全局鉤子的定義方法,如果定義了全局鉤子并通過校驗,就返回所有數據
def clean(self):"""Hook for doing any extra form-wide cleaning after Field.clean() has beencalled on every field. Any ValidationError raised by this method willnot be associated with a particular field; it will have a special-caseassociation with the field named '__all__'."""return self.cleaned_data8、都執行完成后,將錯誤信息保存在第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
執行順序:
轉載于:https://www.cnblogs.com/dxnui119/p/10823277.html
總結
以上是生活随笔為你收集整理的Django13-ModelForm中的is_valid及局部钩子、全局钩子源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 面向对象(数据封装)
- 下一篇: 学习进度10