Django def clean()函數(shù)對表單中的數(shù)據(jù)進行驗證操作
最近寫的資源策略管理,在ceilometer 中創(chuàng)建alarm時,name要求是不能重復的,所以在創(chuàng)建policy的時候,要對policy的name字段進行驗證,而django中正好擁有強大的表單數(shù)據(jù)驗證的功能。
#這是policy中的name字段,在表單的數(shù)據(jù)進行提交的時候,所有的數(shù)據(jù)流會經(jīng)過clean()這個函數(shù)
name = forms.CharField(max_length=255, label=_("Name"))
#在clean函數(shù)中先取出表單中的name字段,在從數(shù)據(jù)庫里面拿到所有的數(shù)據(jù)進行檢查
def clean(self):
cleaned_data = super(CreatePolicyForm, self).clean()
name = cleaned_data.get('name')
try:
policys = api.nova.policy_list(self.request)
except:
exceptions.handle(request,
_('Unable to retrieve policys list.'))
if policys is not None and name is not None:
for policy in policys:
if policy.name.lower() == name.lower():
raise forms.ValidationError(
_('The name "%s" is already used by another policy.')
% name
)
return cleaned_data
補充知識:django中關(guān)于表單自定義驗證器和常用驗證器
常用驗證器:
在驗證某個字段的時候,可以傳遞一個 validators 參數(shù)用來指定驗證器,進一步對數(shù)據(jù)進行過濾。驗證器有很多,但是很多驗證器我們其實已經(jīng)通過這個 Field 或者一些參數(shù)就可以指定了。比如 EmailValidator ,我們可以通過 EmailField 來指定,比如 MaxValueValidator ,我們可以通過 max_value 參數(shù)來指定。
以下是一些常用的驗證器:
1. MaxValueValidator :驗證最大值。
2. MinValueValidator :驗證最小值。
3. MinLengthValidator :驗證最小長度。
4. MaxLengthValidator :驗證最大長度。
5. EmailValidator :驗證是否是郵箱格式。
6. URLValidator :驗證是否是 URL 格式。
7. RegexValidator :如果還需要更加復雜的驗證,那么我們可以通過正則表達式的驗證
器: RegexValidator 。比如現(xiàn)在要驗證手機號碼是否合格,那么我們可以通過以下代碼實
現(xiàn):
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請輸入正確格式的手機號碼!')])
自定義驗證:
有時候?qū)σ粋€字段驗證,不是一個長度,一個正則表達式能夠?qū)懬宄?,還需要一些其他復雜的邏輯,那么我們可以對某個字段,進行自定義的驗證。比如在注冊的表單驗證中,我們想要驗證手機號碼是否已經(jīng)被注冊過了,那么這時候就需要在數(shù)據(jù)庫中進行判斷才知道。對某個字段進行自定義的驗證方式是,定義一個方法,這個方法的名字定義規(guī)則是: clean_fieldname 。如果驗證失敗,那么就拋出一個驗證錯誤。比如要驗證用戶表中手機號碼之前是否在數(shù)據(jù)庫中存在,那么可以通過以下代碼實現(xiàn):
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("手機號碼已經(jīng)存在!")
else:
return telephone
以上是對某個字段進行驗證,如果驗證數(shù)據(jù)的時候,需要針對多個字段進行驗證,那么可以重寫 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('兩個密碼不一致!')
提取錯誤信息:
如果驗證失敗了,那么有一些錯誤信息是我們需要傳給前端的。這時候我們可以通過以下屬性來獲?。?/p>
1. form.errors :這個屬性獲取的錯誤信息是一個包含了 html 標簽的錯誤信息。
2. form.errors.get_json_data() :這個方法獲取到的是一個字典類型的錯誤信息。將某個字段的名字作為 key ,錯誤信息作為值的一個字典。
3. form.as_json() :這個方法是將 form.get_json_data() 返回的字典 dump 成 json 格式的字符串,方便進行傳輸。
4. 上述方法獲取的字段的錯誤值,都是一個比較復雜的數(shù)據(jù)。比如以下:
{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensurethis value has at most 4 characters (it has 22).', 'code': 'max_length'}]}
那么如果我只想把錯誤信息放在一個列表中,而不要再放在一個字典中。這時候我們可以定義一個方法,把這個數(shù)據(jù)重新整理一份。實例代碼如下:
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
這樣就可以把某個字段所有的錯誤信息直接放在這個列表中。
以上這篇Django def clean()函數(shù)對表單中的數(shù)據(jù)進行驗證操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python結(jié)合WPS多維表實現(xiàn)在線批量查詞功能
Python是當前人工智能時代最受歡迎的編程語言,越來越多的應用程序把其整合到自身的功能當中,WPS多維表就是最早接入Python代碼的應用平臺,下面我們就來看看如何在多維表中應用Python代碼實現(xiàn)批量單詞查詢吧2025-12-12
使用TensorFlow搭建一個全連接神經(jīng)網(wǎng)絡教程
今天小編就為大家分享一篇使用TensorFlow搭建一個全連接神經(jīng)網(wǎng)絡教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
python機器學習GCN圖卷積神經(jīng)網(wǎng)絡原理解析
這篇文章主要為大家介紹了GCN圖卷積神經(jīng)網(wǎng)絡原理及代碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05
Python使用Selenium抓取動態(tài)網(wǎng)頁的方法步驟
在如今的網(wǎng)絡中,許多網(wǎng)站是“動態(tài)”的,即網(wǎng)頁內(nèi)容不是靜態(tài)的 HTML 文件,而是由 JavaScript 動態(tài)生成的,這種動態(tài)網(wǎng)頁在數(shù)據(jù)抓取中帶來了一些挑戰(zhàn),在本教程中,我們將詳細介紹如何使用 Python 抓取動態(tài)網(wǎng)頁,需要的朋友可以參考下2024-11-11

