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 = 原来的值

参考:
http://www.cnblogs.com/wupeiqi/articles/6144178.html

posted @ 2017-07-09 18:45  hzxPeter  阅读(230)  评论(0编辑  收藏  举报