日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Django13-ModelForm中的is_valid及局部钩子、全局钩子源码解析

發布時間:2024/7/5 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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.errors

2、查看self.is_bound方法,可以看到data或者files只要有一個不為空,即為真

self.is_bound = data is not None or files is not None

3、查看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._errors

4、查看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_data

7、查看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_data

8、都執行完成后,將錯誤信息保存在第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及局部钩子、全局钩子源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。