day22-Form内置钩子

一、前言

我们之前学习了利用form去验证,form + model 他们两个是分开的,其实在form里面我们django还预留了钩子,这些钩子除了自己验证之外,还有其他一些操作,那有哪些钩子呐?我们来看看:

_clean_fields()  #单个字段验证,对每一个正则表达式验证
_clean_form()   #整体验证
_post_clean()  #最后操作

 就是这三个钩子,下面我们来研究一下它是怎么实现的。

二、源码查看

在obj.is_valid()验证的过程当中,我们存在,其实在这个过程当中,先做了什么,后做了什么,我们下面来看看源码:

1、按住ctrl建 + is_valid()

2、找到self.errors,用同样的方法,查看源码:

3、找到self.full_clean()方法,进去看看:

我们成功找到这个三个钩子

三、单个字段验证

3.1、源码查看(slef._clean_fields)

说明:用上面同样的方法,查看一下self._clean_fields()源码

 

3.2、单个字段验证

说明:根据源码,我们知道在我们自己自定义的form中,是 定义clean_字段名 方法,去验证,然后赋值给 cleaned_data

from app01 import models
from django.core.exceptions import ValidationError  #源码里面抛出的异常
class RegisterForm(forms.Form):
    user = fields.CharField()   #下面的方法要想执行,先通过这边正则验证
    email = fields.EmailField()
    
    #clean_%s 这个函数必须要有返回值,赋值给self.cleaned_data['%s']
    def clean_user(self):
        #注册的时候,如果存在此用户,则报错,没有,则继续执行
        c = models.User.objects.filter(name=self.cleaned_data['user'].count())
        if not c:
            return self.cleaned_data['user']
        else:
            raise ValidationError('用户名已经存在',code="xxxx")  #存在就包异常


    def clean_email(self):

        return self.cleaned_data['email']  #这边必须返回一个值

3.3、注册代码

说明:注册代码如下:

def register(request):
    from app01.forms import RegisterForm

    obj = RegisterForm(request.POST)

    if obj.is_valid():  #验证
        pass

四、整体验证

  上面是注册用户名密码的时候,我们需要进行单个验证,那如果登录的时候,我们只需要告诉你的一个整体的错误,就是你的用户名和密码错误了,那这个就不需要一个一个验证,需要整体去做一个校验,返回一个结果给前端就可以了

4.1、源码剖析(self._clean_form())

1、先找到self.clean_form()源码:

 

2、然后我们看self.clean()方法

4.2、整体验证代码

 说明:我们在登录的时候,抛出一个整体的异常,而不是具体某个异常

from app01 import models
from django.core.exceptions import ValidationError  #源码里面抛出的异常
class RegisterForm(forms.Form):
    user = fields.CharField()   #下面的方法要想执行,先通过这边正则验证
    pwd = fields.CharField()

    #clean_%s 这个函数必须要有返回值,赋值给self.cleaned_data['%s']
    def clean_user(self):
        return self.cleaned_data['user']

    def clean_pwd(self):
        return self.cleaned_data['pwd']  #这边必须返回一个值


    def clean(self):
        c = models.User.objects.filter(name=self.cleaned_data['user'],pwd=self.cleaned_data['pwd']).count()
        if not c:
            return self.cleaned_data  #这边必须有一个返回值,因为源码里面有返回值
        else:
            raise ValidationError("用户名或密码错误",code="xxxxx")  #这个异常应该给整体,不应该给某一个字段

五、最后验证

forms验证的最后一道关,post_clean,去验证。这个目前估计以后或许会用到,主要做一些收尾工作。

5.1、源码剖析(self._post_clean)

说明:其实它什么也没有做,就是forms给你预留的钩子

5.2、使用

from app01 import models
from django.core.exceptions import ValidationError  #源码里面抛出的异常
class RegisterForm(forms.Form):
    user = fields.CharField()
    pwd = fields.CharField(validators=[]) #这边可以正则验证

    #clean_%s 这个函数必须要有返回值,赋值给self.cleaned_data['%s']
    def clean_user(self):
        pass

    def clean_pwd(self):
        pass

    def clean(self):
        pass

    def _post_clean(self):  #最后验证的钩子
        pass

5.3、注册的

def register(request):
    from app01.forms import RegisterForm

    obj = RegisterForm(request.POST)

    if obj.is_valid():
        obj.cleaned_data  #正确的数据
    else:
        obj.errors  #错误的提示

六、错误提示和总结

6.1、错误分为单个错误提示和整体错误提示

obj.errors:
        {
            #self._clean_form() 返回的错误信息,也就是整体返回的错误信息,有的地方写成: NON_FIFLD_ERRORS:[],其实就是代指的__all__
            '__all__':[], 
            # clean_user和clean_pwd返回的错误信息,就是单个验证返回的错误信息
            'user':[{'code':"required",'message':'xxxx'}],
            'pwd':[{'code':"required",'message':'xxxx'}]
        }

6.2、Form操作

数据验证

  • 每一个字段验证(正则,字段钩子),也就是 clean_字段名
  • clean
  • _post_clean

数据验证的顺序图:

 

  

posted @ 2018-05-03 16:17  帅丶高高  阅读(205)  评论(0编辑  收藏  举报