视频加载失败

Django框架Form组件之源码

453 字
2 分钟
Django框架Form组件之源码

【一】切入点#

切入点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

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
Profile Image of the Author
Dream
Hello, I'm Dream.
公告
欢迎来到我的博客!爱学习爱进步。
分类
标签
最新动态
站点统计
文章
300
分类
5
标签
26
总字数
640,882
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录