【一】切入点
切入点
form_obj.is_valid()
def is_valid(self):
"""Return True if the form has no errors, or False otherwise."""
return self.is_bound and not self.errors
- 如果
is_valid
要想返回True- 那么
self.is_bound
要为True self.errors
要为 False
- 那么
【二】self.is_bound
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
initial=None, error_class=ErrorList, label_suffix=None,
empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None):
self.is_bound = data is not None or files is not None
- data 是我们传入的数据
- 只要传入数据有值
- 那么
self.is_bound
一定是True
【三】self.errors
@property
def errors(self):
"""Return an ErrorDict for the data provided for the form."""
if self._errors is None:
self.full_clean()
return self._errors
- forms组件所有的功能基本都出自这个方法
def full_clean(self):
"""
Clean all of self.data and populate self._errors and self.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.
if self.empty_permitted and not self.has_changed():
return
self._clean_fields() # 校验字段
self._clean_form()
self._post_clean()
【1】self._clean_fields() 校验字段 + 局部钩子
def _clean_fields(self):
for name, field in self.fields.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.
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:
value = field.clean(value)
self.cleaned_data[name] = value # 将合法的字段添加到字典里
if hasattr(self, 'clean_%s' % name): # 利用反射获取局部钩子函数
value = getattr(self, 'clean_%s' % name)() # 局部钩子需要有返回值
self.cleaned_data[name] = value
except ValidationError as e:
self.add_error(name, e) # 添加提示信息
循环获取字段对象
-
局部钩子报错也可以使用
ValidationError
主动抛出异常- 较为繁琐,一般不用
【2】_clean_form
全局钩子
def _clean_form(self):
try:
cleaned_data = self.clean() # 调用父类的clean方法或者自定义的clean方法
except ValidationError as e:
self.add_error(None, e)
else:
if cleaned_data is not None:
self.cleaned_data = cleaned_data
【3】_post_clean
def _post_clean(self):
"""
An internal hook for performing additional cleaning after form cleaning
is complete. Used for model validation in model forms.
"""
pass
标签:None,20.5,Form,self,value,field,源码,clean,data
From: https://www.cnblogs.com/dream-ze/p/18081779