1. is_valid如果返回值如果为真 证明验证成功 意味着self.is_bound为True 和 self.errors为False
def is_valid(self):
return self.is_bound and not self.errors
1).那么self.is_bound什么时候为真呢? 通过源码发现只有当实例化带参数的值时 self.is_bound 才为真 默认会把传入的值赋值给data data有值时 self.is_bound为真
2).那么self.errors什么时候为假呢? 请看下面
2. 类初始化时候self._errors为None 所以此时会执行 self.full_clean()
@property
def errors(self):
if self._errors is None:
self.full_clean()
return self._errors
3. 这部分代码的 最后生成 self.cleaned_data = {} 然后分别执行底下三个方法
def full_clean(self):
self._errors = ErrorDict()
# 当用户提交数据时self.is_bound为真 not Ture代为为假 所以这部分不执行
if not self.is_bound:
return
# 创建一个 {}
self.cleaned_data = {}
if self.empty_permitted and not self.has_changed():
return
# 循环验证字段和字段对应的值 和钩子函数 如果验证成功 把字段和字段对应的值加入到self.cleand_data里面 错误会加入到self.errors里面
self._clean_fields()
# 执行self.clean()函数 默认返回self.cleaned_data 可以在子类中子定义self.clean() 方法
self._clean_form()
self._post_clean()
4. 循环类里面的字段 如果验证成功 将字段名和值 加入self.cleaned_data 例如: self.cleaned_data = {'username': 'alex'}
接着会找clean_字段名 的钩子函数,如果有此函数例如clean_username(),会执行此函数,并把结果覆盖 self.cleaned_data = {'username': 结果}
当循环完 username 会循环 password
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:
value = field.clean(value)
# 将name和value增加到 self.cleaned_data 字典里面
self.cleaned_data[name] = value
# 判断有没有 clean_字段 的函数 如果有 会覆盖上面self.cleaned_data对应的值
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError as e:
# 如果验证错误 会把错误信息 加入到self.errors里面
self.add_error(name, e)
- is_valid
- 字段 = 默认正则表达式
- 额外的正则
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
class MyForm(Form):
user = fields.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
- clean_字段,必须返回值
- clean()
有返回值:cleaned_data = 返回值
无返回值:cleaned_data = 原来的值
from django.core.exceptions import ValidationError
class TestForm(Form):
user = fields.CharField(validators=[])
pwd = fields.CharField()
#对单个字段做验证
def clean_user(self):
v = self.cleaned_data['user']
if models.Student.objects.filter(name=v).count():
raise ValidationError('用户名已经存在')
return self.cleaned_data['user']
def clean_pwd(self):
return self.cleaned_data['pwd']
#对整体所有的值做验证,如果数据库有值,抛异常
def clean(self):
user = self.cleaned_data.get('user')
email = self.cleaned_data.get('email')
if models.Student.objects.filter(user=user,email=email).count():
raise ValidationError('用户名和邮箱联合已经存在')
return self.cleaned_data
def _post_clean(self):
"""
An internal hook for performing additional cleaning after form cleaning
is complete. Used for model validation in model forms.
"""
pass