概述
django框架提供了一個forms類,來處理web開發中的表單相關事項。衆所周知,form最常作的是對用戶輸入的內容進行驗證,爲此django的forms類提供了全面的內容驗證支持。html
驗證過程
流程詳解
- 函數full_clean()依次調用每一個field的clean()函數,該函數針對field的max_length,unique等約束進行驗證,若是驗證成功則返回值,不然拋出ValidationError錯誤。若是有值返回,則放入form的cleaned_data字典中。
- 若是每一個field的內置clean()函數沒有拋出ValidationError錯誤,則調用以clean_開頭,以field名字結尾的自定義field驗證函數。驗證成功和失敗的處理方式同步驟1。
- 最後,調用form的clean()函數——注意,這裏是form的clean(),而不是field的clean()——若是clean沒有錯誤,那麼它將返回cleaned_data字典。
- 若是到這一步沒有ValidationError拋出,那麼cleaned_data字典就填滿了有效數據。不然cleaned_data不存在,form的另一個字典errors填上驗證錯誤。在template中,每一個field獲取本身錯誤的方式是:{{ form.username.errors }}。
- 最後,若是有錯誤is_valid()返回False,不然返回True。
注意一點:自定義驗證機制時:clean()和clean_&()的最後必須返回驗證完畢或修改後的值.web
form驗證中自定義驗證機制
需求
- 用戶輸入的是否爲cc,若是是,提示用戶
- 驗證二次輸入的密碼是否匹配,若是不一致,提示用戶
看下views.py中的代碼:django
... from django import forms from django.core.exceptions import ValidationError import re def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') ifnot mobile_re.match(value): raise ValidationError('手機號碼格式錯誤') class LoginForm(forms.Form): user = forms.CharField(required=True, error_messages={'required': '用戶名不能爲空.'}) pwd = forms.CharField(required=True, min_length=6, max_length=10, error_messages={'required': '密碼不能爲空.', 'min_length': "至少6位"}) pwd2 = forms.CharField(required=True, min_length=6, max_length=10, error_messages={'required': '密碼不能爲空.', 'min_length': "至少6位"}) num = forms.IntegerField(error_messages={'required': '數字不能空.', 'invalid': '必須輸入數字'}) phone = forms.CharField(validators=[mobile_validate, ], ) def clean_user(self): user = self.cleaned_data.get('user') if user == 'cc': raise forms.ValidationError('用戶名是個人!') return user def clean(self): cleaned_data = self.cleaned_data pwd = cleaned_data['pwd'] pwd2 = cleaned_data['pwd2'] print(pwd,pwd2) if pwd != pwd2: raise forms.ValidationError('二次輸入密碼不匹配') return cleaned_data #注意此處必定要return clean_data,不然會報錯
def login(request):
if request.POST: objPost = LoginForm(request.POST) ret = objPost.is_valid() if ret: print(objPost.clean()) else: from django.forms.utils import ErrorDict print(objPost.non_field_errors()) passreturn render(request, 'login.html', {'obj1': objPost}) else: objGet = LoginForm() return render(request, 'login.html', {'obj1': objGet}) ...
HTML 頁面中,若是想取clean()報錯的信息,因其自己是一個迭代器,因此咱們能夠循環返回數據的non_field_errors
取值,好比:框架
<div>{% if obj1.non_field_errors %}{% for item in obj1.non_field_errors %}<spanclass="error_msg">{{ item }}span>{% endfor %}{% endif %}
我來看下html中的設置:函數
<htmllang="en"><head><metacharset="UTF-8"><title>title><style>.error_msg{ color: red; } style>head><body><formaction="/login/"method="POST"><div>用戶名: {{ obj1.user }}{% if obj1.errors.user %}<spanclass="error_msg">{{ obj1.errors.user.0 }}span>{% endif %}div><div>密碼: {{ obj1.pwd }}{% if obj1.errors.pwd %}<spanclass="error_msg">{{ obj1.errors.pwd.0 }}span>{% endif %}div><div>確認密碼: {{ obj1.pwd2 }}{% if obj1.errors.pwd2 %}<spanclass="error_msg">{{ obj1.errors.pwd2.0 }}span>{% endif %}div><div>數字: {{ obj1.num }}{% if obj1.errors.num %}<spanclass="error_msg">{{ obj1.errors.num.0 }}span>{% endif %}div><div>電話: {{ obj1.phone }}{% if obj1.errors.phone %}<spanclass="error_msg">{{ obj1.errors.phone.0 }}span>{% endif %}div><div>{% if obj1.non_field_errors %}{% for item in obj1.non_field_errors %}<spanclass="error_msg">{{ item }}span>{% endfor %}{% endif %}div><inputtype="submit"value="提交"/>form>body>html>