在前面的例子裏面 http://beanxyz.blog.51cto.com/5570417/1963702,已經演示了form能夠自動地對正則進行合法的判斷,若是不合法,會直接顯示錯誤信息。python
可是這個功能並不完善,好比說一個數據可能正則判斷合法了,可是不符合惟一性的判斷,那麼怎麼處理?咱們能夠經過 form的 hook(鉤子)進行自定義。django
若是咱們查看 Is_valid這個方法,咱們能夠看見app
def is_valid(self): """ Returns True if the form has no errors. Otherwise, False. If errors are being ignored, returns False. """ return self.is_bound and not self.errors
追蹤self.errorside
@property def errors(self): "Returns an ErrorDict for the data provided for the form" if self._errors is None: self.full_clean() return self._errors
追蹤 full_clean(), 這裏是系統給咱們預留的3個hook,分別表明對字段的clean,對整個form的clean,和clean以後的操做post
def full_clean(self): """ Cleans all of self.data and populates self._errors and self.cleaned_data. """ self._errors = ErrorDict() if not self.is_bound: # Stop further processing. return self.cleaned_data = {} # If the form is permitted to be empty, and none of the form data has # changed from the initial data, short circuit any validation. if self.empty_permitted and not self.has_changed(): return self._clean_fields() self._clean_form() self._post_clean()
所以form驗證的順序是,默認的正則判斷-》對應每個字段單獨的驗證(clean)-》整個form的clean驗證-》clean以後的操做ui
實例:code
from django.core.exceptions import ValidationError from django import forms from django.forms import widgets from django.forms import fields from app01 import models class RegisterForm(forms.Form): user = fields.CharField email = fields.EmailField def clean_user(self): # 對user作一個單獨的驗證 c = models.UserType.objects.filter(name=self.cleaned_data['user']) if c : # 若是用戶名已經存在,提示報錯信息 raise ValidationError('用戶名已經存在',code='xxx') else: # 不存在,驗證經過 return self.cleaned_data['user'] def clean_email(self): # 對email作單獨的驗證 # 驗證必需要有返回值 return self.cleaned_data['email'] # 驗證順序: # 先user字段,在clean_user方法 # 再email字段,在clean_email方法 def register(request): from cmdb.forms import RegisterForm from django.core.exceptions import NON_FIELD_ERRORS obj = RegisterForm(request.POST) if obj.is_valid(): obj.cleand_data else: obj.errors { 'user':[{'code':'required','message':'xxxx'}], 'pwd':[{'code':'required','message':'xxxx'}], # 上面每一個字段的錯誤信息放在裏面,那clean總的錯誤信息放在哪裏? '__all__':[], # 特殊的總體錯誤信息,放在這裏 # NON_FIELD_ERRORS:[], 和 __all__ 一個意思。 }