Form组件的验证流程及扩展(钩子)
常用的form
class TestForm(Form):
t1 = fields.CharField(
widget=widgets.Textarea # 输入框
)
t2 = fields.CharField(
widget=widgets.CheckboxInput # 单选框
)
t3 = fields.MultipleChoiceField(
choices=[(1, '篮球'), (2, '足球')], # 多选框的内容
widget=widgets.CheckboxSelectMultiple # 多选框
)
t4 = fields.ChoiceField(
choices=[(1, '篮球'), (2, '足球')],
widget=widgets.RadioSelect # 单选 互斥
)
t5 = fields.FileField(
widget=widgets.FileInput # 文件 最终获得是文件对象
)
def test(request):
obj = TestForm(initial={'t3': [2, ]}) # 多选的默认
return render(request, 'test.html', {'obj': obj})
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ obj.t1 }}
{{ obj.t2 }}
{{ obj.t3 }}
{{ obj.t4 }}
{{ obj.t5 }}
</body>
</html>
Form组件的验证流程
关键点是返回值
- 进行正则验证
- 循环所有的字段,加入self.fields中并执行相应的函数clean_xxx,xxx是字段的名字
- 自己定义的高级验证一定要有返回值,默认是自己
源码的寻找循序:
is_valid -> errors -> full_clean -> self._clean_fields()
源码中的full_clean
self._clean_fields() # 对定义的字段函数进行验证
self._clean_form() # clean整体验证
self._post_clean() # 最后自定义验证 一般不适用,需要自己写错误验证
1 自定义函数进行验证
自定义的函数是对每个字段进行验证,
from django.core.exceptions import ValidationError
class TestForm(Form):
user = fields.CharField()
pwd = fields.CharField()
def clean_user(self):
v = self.cleaned_data['user']
if models.Students.objects.filter(name=v).count():
raise ValidationError('用户名已经存在', code='invalid') # 默认是invalid 还可以是其他的required
else:
pass
return self.cleaned_data['user'] # 一定要有返回值 否则cleaned_data就是None,
# 没有改变就把自身返回
def clean_pwd(self):
return self.cleaned_data['pwd'] # self代表的是obj对象
2 整体验证
使用clean对整体进行验证,内部已经提供了异常处理
class TestForm(Form):
user = fields.CharField()
pwd = fields.CharField()
def clean_user(self):
v = self.cleaned_data['user']
if models.Students.objects.filter(name=v).count():
raise ValidationError('用户名已经存在', code='invalid') # 默认是invalid 还可以是其他的required
else:
pass
return self.cleaned_data['user'] # 一定要有返回值 否则cleaned_data就是None,
# 没有改变就把自身返回
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.Students.objects.filter(user=user, email=email).count():
raise ValidationError('用户名和邮箱联合存在')
return self.cleaned_data
3 在默认正则中添加正则
需要导入一个模块
关键在validators=[],在内部添加正则,如第一个没有通过验证,后面的也就不用进行验证了
from django.core.validators import RegexValidator
class TestForm(Form):
# user = fields.CharField(validators=[])
user = fields.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
pwd = fields.CharField()
总结:
-
字段 = 默认正则表达式
额外的正则 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 = 原来的值