is_valid校验机制
生活随笔
收集整理的這篇文章主要介紹了
is_valid校验机制
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
先來歸納一下整個(gè)流程 (1)首先is_valid()起手,看seld.errors中是否值,只要有值就是flase
(2)接著分析errors.里面判斷_errors是都為空,如果為空返回self.full_clean(),否則返回self._errors
(3)現(xiàn)在就要看full_clean(),是何方神圣了,里面設(shè)置_errors和cleaned_data這兩個(gè)字典,一個(gè)存錯(cuò)誤字段,一個(gè)存儲(chǔ)正確字段。
(4)在full_clean最后有一句self._clean_fields(),表示校驗(yàn)字段
(5)在_clean_fields函數(shù)中開始循環(huán)校驗(yàn)每個(gè)字段,真正校驗(yàn)字段的是field.clean(value),怎么校驗(yàn)的不管
(6)在_clean_fields中可以看到,會(huì)將字段分別添加到_errors和cleaned_data這兩個(gè)字典中
(7)結(jié)尾部分還設(shè)置了鉤子,找clean_XX形式的,有就執(zhí)行。執(zhí)行錯(cuò)誤信息也會(huì)添加到_errors中
(8)整個(gè)校驗(yàn)過程完成
下面分析form組件中is_valid校驗(yàn)的流程
在分析過程中重點(diǎn)關(guān)注_erroes和clean_data這兩個(gè)字典 def login(request):if request.method == "POST":form_obj = LoginForm(request.POST)if form_obj.is_valid():#如果檢驗(yàn)全部通過print(form_obj.clean_data) #這里全部都沒問題return HttpResponse("你好,歡迎回來!")else:#print(form_obj.clean_data)#print(form_obj.errors)return render(request, "login.html", {"form_obj": form_obj,)form_obj = LoginForm()return render(request, "login.html", {"form_obj": form_obj}) 鉤子代碼實(shí)例 def clean_user(self):val1 = self.cleaned_data.get("user")#從正確的字段字典中取值#如果這個(gè)字符串全部都是由數(shù)組組成if not val1.isdigit():return val1else:# 注意這個(gè)報(bào)錯(cuò)信息已經(jīng)確定了raise ValidationError("用戶名不能全部是數(shù)字組成")#在校驗(yàn)的循環(huán)中except ValidationError as e:,捕捉的就是這個(gè)異常#所以能將錯(cuò)誤信息添加到_errors中#代碼分析部分 def is_valid(self):"""Returns True if the form has no errors. Otherwise, False. If errors arebeing ignored, returns False.如果表單沒有錯(cuò)誤,則返回true。否則為假。如果錯(cuò)誤是被忽略,返回false。"""return self.is_bound and not self.errors#is_bound默認(rèn)有值#只要self.errors中有一個(gè)值,not True = false,返回的就是falsedef errors(self):"""Returns an ErrorDict for the data provided for the form返回一個(gè)ErrorDict在form表單存在的前提下"""if self._errors is None:self.full_clean()return self._errorsdef full_clean(self):"""Cleans all of self.data and populates self._errors and self.cleaned_data.清除所有的self.data和本地的self._errors和selif.cleaned_data"""self._errors = ErrorDict()if not self.is_bound: # Stop further processing.停止進(jìn)一步的處理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.#如果表單允許為空,和原始數(shù)據(jù)也是空的話,允許不進(jìn)行任何驗(yàn)證"""if self.empty_permitted and not self.has_changed():returnself._clean_fields() #字面意思校驗(yàn)字段 self._clean_form()self._post_clean()def _clean_fields(self):#每個(gè)form組件實(shí)例化的過程中都會(huì)創(chuàng)建一個(gè)fields。fields實(shí)質(zhì)上是一個(gè)字典。#儲(chǔ)存著類似{"user":"user規(guī)則","pwd":"pwd的規(guī)則對(duì)象"}for name, field in self.fields.items():#name是你調(diào)用的一個(gè)個(gè)規(guī)則字段,field是調(diào)用字段的規(guī)則#items是有順序的,因?yàn)樗r?yàn)字段的一致性"""# value_from_datadict() gets the data from the data dictionaries.# Each widget type knows how to retrieve its own data, because some# widgets split data over several HTML fields.value_from_datadict()從數(shù)據(jù)字典中獲取數(shù)據(jù)。每個(gè)部件類型知道如何找回自己的數(shù)據(jù),因?yàn)橛行┎考鸱謹(jǐn)?shù)據(jù)在幾個(gè)HTML字段。"""#現(xiàn)在假設(shè)第一個(gè)字段是userif 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): #判斷是不是文件#你是文件的時(shí)候怎么校驗(yàn)initial = self.get_initial_for_field(field, name)value = field.clean(value, initial)#filed是一個(gè)對(duì)象,field.clean才是真正的規(guī)則校驗(yàn)else:#你不是文件的時(shí)候怎么校驗(yàn)#實(shí)際中也是走的這一部,value是你輸入的字段值#如果沒有問題,那么原樣返回value = field.clean(value)#如果一旦出現(xiàn)問題,那么就會(huì)走except中的代碼self.cleaned_data[name] = valueif hasattr(self, 'clean_%s' % name): #這里找是否有clean_XX這個(gè)名字存在value = getattr(self, 'clean_%s' % name)() #如果有執(zhí)行這個(gè)函數(shù)self.cleaned_data[name] = value #而在鉤子中必須報(bào)錯(cuò)的返回值是確定的#如果上面有問題,就又把錯(cuò)誤添加到了_error中#上面這三行代碼是我們能添加鉤子的原因,而且規(guī)定了鉤子名的格式#如果這個(gè)值是正確的話,就會(huì)給這個(gè)字典添加一個(gè)鍵值對(duì)#剛才在full_clean中self.cleaned_data = {}已經(jīng)初始化了。#{”pws“:123}except ValidationError as e:self.add_error(name, e)#如果出現(xiàn)錯(cuò)誤,就會(huì)給_error這個(gè)字典添加一個(gè)鍵值對(duì)#至于add_error這個(gè)函數(shù)如何添加這個(gè)鍵值對(duì)的,我們先不管#鍵就是name,值就是錯(cuò)誤信息e#在full_clean中已經(jīng)初始化self._errors = ErrorDict()#假設(shè)現(xiàn)在user有問題,那么_error就是這樣{”user“:e} View Code
(2)接著分析errors.里面判斷_errors是都為空,如果為空返回self.full_clean(),否則返回self._errors
(3)現(xiàn)在就要看full_clean(),是何方神圣了,里面設(shè)置_errors和cleaned_data這兩個(gè)字典,一個(gè)存錯(cuò)誤字段,一個(gè)存儲(chǔ)正確字段。
(4)在full_clean最后有一句self._clean_fields(),表示校驗(yàn)字段
(5)在_clean_fields函數(shù)中開始循環(huán)校驗(yàn)每個(gè)字段,真正校驗(yàn)字段的是field.clean(value),怎么校驗(yàn)的不管
(6)在_clean_fields中可以看到,會(huì)將字段分別添加到_errors和cleaned_data這兩個(gè)字典中
(7)結(jié)尾部分還設(shè)置了鉤子,找clean_XX形式的,有就執(zhí)行。執(zhí)行錯(cuò)誤信息也會(huì)添加到_errors中
(8)整個(gè)校驗(yàn)過程完成
下面分析form組件中is_valid校驗(yàn)的流程
在分析過程中重點(diǎn)關(guān)注_erroes和clean_data這兩個(gè)字典 def login(request):if request.method == "POST":form_obj = LoginForm(request.POST)if form_obj.is_valid():#如果檢驗(yàn)全部通過print(form_obj.clean_data) #這里全部都沒問題return HttpResponse("你好,歡迎回來!")else:#print(form_obj.clean_data)#print(form_obj.errors)return render(request, "login.html", {"form_obj": form_obj,)form_obj = LoginForm()return render(request, "login.html", {"form_obj": form_obj}) 鉤子代碼實(shí)例 def clean_user(self):val1 = self.cleaned_data.get("user")#從正確的字段字典中取值#如果這個(gè)字符串全部都是由數(shù)組組成if not val1.isdigit():return val1else:# 注意這個(gè)報(bào)錯(cuò)信息已經(jīng)確定了raise ValidationError("用戶名不能全部是數(shù)字組成")#在校驗(yàn)的循環(huán)中except ValidationError as e:,捕捉的就是這個(gè)異常#所以能將錯(cuò)誤信息添加到_errors中#代碼分析部分 def is_valid(self):"""Returns True if the form has no errors. Otherwise, False. If errors arebeing ignored, returns False.如果表單沒有錯(cuò)誤,則返回true。否則為假。如果錯(cuò)誤是被忽略,返回false。"""return self.is_bound and not self.errors#is_bound默認(rèn)有值#只要self.errors中有一個(gè)值,not True = false,返回的就是falsedef errors(self):"""Returns an ErrorDict for the data provided for the form返回一個(gè)ErrorDict在form表單存在的前提下"""if self._errors is None:self.full_clean()return self._errorsdef full_clean(self):"""Cleans all of self.data and populates self._errors and self.cleaned_data.清除所有的self.data和本地的self._errors和selif.cleaned_data"""self._errors = ErrorDict()if not self.is_bound: # Stop further processing.停止進(jìn)一步的處理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.#如果表單允許為空,和原始數(shù)據(jù)也是空的話,允許不進(jìn)行任何驗(yàn)證"""if self.empty_permitted and not self.has_changed():returnself._clean_fields() #字面意思校驗(yàn)字段 self._clean_form()self._post_clean()def _clean_fields(self):#每個(gè)form組件實(shí)例化的過程中都會(huì)創(chuàng)建一個(gè)fields。fields實(shí)質(zhì)上是一個(gè)字典。#儲(chǔ)存著類似{"user":"user規(guī)則","pwd":"pwd的規(guī)則對(duì)象"}for name, field in self.fields.items():#name是你調(diào)用的一個(gè)個(gè)規(guī)則字段,field是調(diào)用字段的規(guī)則#items是有順序的,因?yàn)樗r?yàn)字段的一致性"""# value_from_datadict() gets the data from the data dictionaries.# Each widget type knows how to retrieve its own data, because some# widgets split data over several HTML fields.value_from_datadict()從數(shù)據(jù)字典中獲取數(shù)據(jù)。每個(gè)部件類型知道如何找回自己的數(shù)據(jù),因?yàn)橛行┎考鸱謹(jǐn)?shù)據(jù)在幾個(gè)HTML字段。"""#現(xiàn)在假設(shè)第一個(gè)字段是userif 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): #判斷是不是文件#你是文件的時(shí)候怎么校驗(yàn)initial = self.get_initial_for_field(field, name)value = field.clean(value, initial)#filed是一個(gè)對(duì)象,field.clean才是真正的規(guī)則校驗(yàn)else:#你不是文件的時(shí)候怎么校驗(yàn)#實(shí)際中也是走的這一部,value是你輸入的字段值#如果沒有問題,那么原樣返回value = field.clean(value)#如果一旦出現(xiàn)問題,那么就會(huì)走except中的代碼self.cleaned_data[name] = valueif hasattr(self, 'clean_%s' % name): #這里找是否有clean_XX這個(gè)名字存在value = getattr(self, 'clean_%s' % name)() #如果有執(zhí)行這個(gè)函數(shù)self.cleaned_data[name] = value #而在鉤子中必須報(bào)錯(cuò)的返回值是確定的#如果上面有問題,就又把錯(cuò)誤添加到了_error中#上面這三行代碼是我們能添加鉤子的原因,而且規(guī)定了鉤子名的格式#如果這個(gè)值是正確的話,就會(huì)給這個(gè)字典添加一個(gè)鍵值對(duì)#剛才在full_clean中self.cleaned_data = {}已經(jīng)初始化了。#{”pws“:123}except ValidationError as e:self.add_error(name, e)#如果出現(xiàn)錯(cuò)誤,就會(huì)給_error這個(gè)字典添加一個(gè)鍵值對(duì)#至于add_error這個(gè)函數(shù)如何添加這個(gè)鍵值對(duì)的,我們先不管#鍵就是name,值就是錯(cuò)誤信息e#在full_clean中已經(jīng)初始化self._errors = ErrorDict()#假設(shè)現(xiàn)在user有問題,那么_error就是這樣{”user“:e} View Code
?
轉(zhuǎn)載于:https://www.cnblogs.com/ALADL/p/9846204.html
總結(jié)
以上是生活随笔為你收集整理的is_valid校验机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity中sharedMaterial
- 下一篇: [bzoj2893] 集合计数