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
数据验证的顺序图: