Django之form组件is_valid校验机制#先来归纳⼀下整个流程
#(1)⾸先is_valid()起⼿,看s中是否值,只要有值就是flase
#(2)接着分析errors.⾥⾯判断_errors是都为空,如果为空返回self.full_clean(),否则返回self._errors
#(3)现在就要看full_clean(),是何⽅神圣了,⾥⾯设置_errors和cleaned_data这两个字典,⼀个存错误字段,⼀个存储正确字段。#(4)在full_clean最后有⼀句self._clean_fields(),表⽰校验字段
#(5)在_clean_fields函数中开始循环校验每个字段,真正校验字段的是field.clean(value),怎么校验的不管
#(6)在_clean_fields中可以看到,会将字段分别添加到_errors和cleaned_data这两个字典中
#(7)结尾部分还设置了钩⼦,clean_XX形式的,有就执⾏。执⾏错误信息也会添加到_errors中
#(8)整个校验过程完成
#下⾯分析form组件中is_valid校验的流程
#在分析过程中重点关注_erroes和clean_data这两个字典
def login(request):
hod == "POST":
form_obj = LoginForm(request.POST)
if form_obj.is_valid():
#如果检验全部通过
print(form_obj.clean_data) #这⾥全部都没问题
return HttpResponse("你好,欢迎回来!")
else:
#print(form_obj.clean_data)
#print(s)
return render(request, "login.html", {"form_obj": form_obj,)
form_obj = LoginForm()
return render(request, "login.html", {"form_obj": form_obj})
#钩⼦代码实例
def clean_user(self):
val1 = self.("user")
#从正确的字段字典中取值
#如果这个字符串全部都是由数组组成
if not val1.isdigit():
return val1
else:
# 注意这个报错信息已经确定了
raise ValidationError("⽤户名不能全部是数字组成")
#在校验的循环中except ValidationError as e:,捕捉的就是这个异常
#所以能将错误信息添加到_errors中
#代码分析部分
def is_valid(self):
"""
Returns True if the form has no errors. Otherwise, False. If errors are
being ignored, returns False.
如果表单没有错误,则返回true。否则为假。如果错误是被忽略,返回false。
"""
return self.is_bound and s
#is_bound默认有值
#只要s中有⼀个值,not True = false,返回的就是false
def errors(self):
"""
Returns an ErrorDict for the data provided for the form
返回⼀个ErrorDict在form表单存在的前提下
"""
if self._errors is None:
self.full_clean()
return self._errors
def 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.停⽌进⼀步的处理
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.
#如果表单允许为空,和原始数据也是空的话,允许不进⾏任何验证
"""
pty_permitted and not self.has_changed():
return
self._clean_fields()  #字⾯意思校验字段
self._clean_form()
self._post_clean()
def _clean_fields(self):
#每个form组件实例化的过程中都会创建⼀个fields。fields实质上是⼀个字典。
#储存着类似{"user":"user规则","pwd":"pwd的规则对象"}
for name, field in self.fields.items():
#name是你调⽤的⼀个个规则字段,field是调⽤字段的规则
#items是有顺序的,因为他要校验字段的⼀致性
"""
# 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()从数据字典中获取数据。
每个部件类型知道如何回⾃⼰的数据,因为有些部件拆分数据在⼏个HTML字段。
"""
#现在假设第⼀个字段是user
if field.disabled:
value = _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 = _initial_for_field(field, name)
value = field.clean(value, initial)
#filed是⼀个对象,field.clean才是真正的规则校验
else:
#你不是⽂件的时候怎么校验
#实际中也是⾛的这⼀部,value是你输⼊的字段值
#如果没有问题,那么原样返回
printformvalue = field.clean(value)
#如果⼀旦出现问题,那么就会⾛except中的代码
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):  #这⾥是否有clean_XX这个名字存在
value = getattr(self, 'clean_%s' % name)()  #如果有执⾏这个函数
self.cleaned_data[name] = value  #⽽在钩⼦中必须报错的返回值是确定的
#如果上⾯有问题,就⼜把错误添加到了_error中
#上⾯这三⾏代码是我们能添加钩⼦的原因,⽽且规定了钩⼦名的格式
#如果这个值是正确的话,就会给这个字典添加⼀个键值对
#刚才在full_clean中self.cleaned_data = {}已经初始化了。
#{”pws“:123}
except ValidationError as e:
self.add_error(name, e)
#如果出现错误,就会给_error这个字典添加⼀个键值对
#⾄于add_error这个函数如何添加这个键值对的,我们先不管
#键就是name,值就是错误信息e
#在full_clean中已经初始化self._errors = ErrorDict()
#假设现在user有问题,那么_error就是这样{”user“:e}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。