Form组件的验证流程及扩展(钩子)
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 = 原来的值

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号