用表單驗證數據
常用的Field:
使用Field
可以是對數據驗證的第一步。你期望這個提交上來的數據是什么類型,那么就使用什么類型的Field
。
CharField:
用來接收文本。
參數:
- max_length:這個字段值的最大長度。
- min_length:這個字段值的最小長度。
- required:這個字段是否是必須的。默認是必須的。
- error_messages:在某個條件驗證失敗的時候,給出錯誤信息。
EmailField:
用來接收郵件,會自動驗證郵件是否合法。
錯誤信息的key:required
、invalid
。
FloatField:
用來接收浮點類型,并且如果驗證通過后,會將這個字段的值轉換為浮點類型。
參數:
- max_value:最大的值。
- min_value:最小的值。
錯誤信息的key:required
、invalid
、max_value
、min_value
。
IntegerField:
用來接收整形,并且驗證通過后,會將這個字段的值轉換為整形。
參數:
- max_value:最大的值。
- min_value:最小的值。
錯誤信息的key:required
、invalid
、max_value
、min_value
。
URLField:
用來接收url
格式的字符串。
錯誤信息的key:required
、invalid
。
常用驗證器:
在驗證某個字段的時候,可以傳遞一個validators
參數用來指定驗證器,進一步對數據進行過濾。驗證器有很多,但是很多驗證器我們其實已經通過這個Field
或者一些參數就可以指定了。比如EmailValidator
,我們可以通過EmailField
來指定,比如MaxValueValidator
,我們可以通過max_value
參數來指定。以下是一些常用的驗證器:
MaxValueValidator
:驗證最大值。MinValueValidator
:驗證最小值。MinLengthValidator
:驗證最小長度。MaxLengthValidator
:驗證最大長度。EmailValidator
:驗證是否是郵箱格式。URLValidator
:驗證是否是URL
格式。-
RegexValidator
:如果還需要更加復雜的驗證,那么我們可以通過正則表達式的驗證器:RegexValidator
。比如現在要驗證手機號碼是否合格,那么我們可以通過以下代碼實現:class MyForm(forms.Form): telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
自定義驗證:
有時候對一個字段驗證,不是一個長度,一個正則表達式能夠寫清楚的,還需要一些其他復雜的邏輯,那么我們可以對某個字段,進行自定義的驗證。比如在注冊的表單驗證中,我們想要驗證手機號碼是否已經被注冊過了,那么這時候就需要在數據庫中進行判斷才知道。對某個字段進行自定義的驗證方式是,定義一個方法,這個方法的名字定義規則是:clean_fieldname
。如果驗證失敗,那么就拋出一個驗證錯誤。比如要驗證用戶表中手機號碼之前是否在數據庫中存在,那么可以通過以下代碼實現:
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
def clean_telephone(self):
telephone = self.cleaned_data.get('telephone')
exists = User.objects.filter(telephone=telephone).exists()
if exists:
raise forms.ValidationError("手機號碼已經存在!")
return telephone
以上是對某個字段進行驗證,如果驗證數據的時候,需要針對多個字段進行驗證,那么可以重寫clean
方法。比如要在注冊的時候,要判斷提交的兩個密碼是否相等。那么可以使用以下代碼來完成:
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
pwd1 = forms.CharField(max_length=12)
pwd2 = forms.CharField(max_length=12)
def clean(self):
cleaned_data = super().clean()
pwd1 = cleaned_data.get('pwd1')
pwd2 = cleaned_data.get('pwd2')
if pwd1 != pwd2:
raise forms.ValidationError('兩個密碼不一致!')
提取錯誤信息:
如果驗證失敗了,那么有一些錯誤信息是我們需要傳給前端的。這時候我們可以通過以下屬性來獲取:
-
form.errors
:這個屬性獲取的錯誤信息是一個包含了html
標簽的錯誤信息。 -
form.errors.get_json_data()
:這個方法獲取到的是一個字典類型的錯誤信息。將某個字段的名字作為key
,錯誤信息作為值的一個字典。 -
form.as_json()
:這個方法是將form.get_json_data()
返回的字典dump
成json
格式的字符串,方便進行傳輸。 - 上述方法獲取的字段的錯誤值,都是一個比較復雜的數據。比如以下:
{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensure this value has at most 4 characters (it has 22).', 'code': 'max_length'}]}
那么如果我只想把錯誤信息放在一個列表中,而不要再放在一個字典中。這時候我們可以定義一個方法,把這個數據重新整理一份。實例代碼如下:
class MyForm(forms.Form):
username = forms.URLField(max_length=4)
def get_errors(self):
errors = self.errors.get_json_data()
new_errors = {}
for key,message_dicts in errors.items():
messages = []
for message in message_dicts:
messages.append(message['message'])
new_errors[key] = messages
return new_errors
這樣就可以把某個字段所有的錯誤信息直接放在這個列表中。