Django def clean()函數(shù)對(duì)表單中的數(shù)據(jù)進(jìn)行驗(yàn)證操作
最近寫的資源策略管理,在ceilometer 中創(chuàng)建alarm時(shí),name要求是不能重復(fù)的,所以在創(chuàng)建policy的時(shí)候,要對(duì)policy的name字段進(jìn)行驗(yàn)證,而django中正好擁有強(qiáng)大的表單數(shù)據(jù)驗(yàn)證的功能。
#這是policy中的name字段,在表單的數(shù)據(jù)進(jìn)行提交的時(shí)候,所有的數(shù)據(jù)流會(huì)經(jīng)過(guò)clean()這個(gè)函數(shù)
name = forms.CharField(max_length=255, label=_("Name"))
#在clean函數(shù)中先取出表單中的name字段,在從數(shù)據(jù)庫(kù)里面拿到所有的數(shù)據(jù)進(jìn)行檢查 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
補(bǔ)充知識(shí):django中關(guān)于表單自定義驗(yàn)證器和常用驗(yàn)證器
常用驗(yàn)證器:
在驗(yàn)證某個(gè)字段的時(shí)候,可以傳遞一個(gè) validators 參數(shù)用來(lái)指定驗(yàn)證器,進(jìn)一步對(duì)數(shù)據(jù)進(jìn)行過(guò)濾。驗(yàn)證器有很多,但是很多驗(yàn)證器我們其實(shí)已經(jīng)通過(guò)這個(gè) Field 或者一些參數(shù)就可以指定了。比如 EmailValidator ,我們可以通過(guò) EmailField 來(lái)指定,比如 MaxValueValidator ,我們可以通過(guò) max_value 參數(shù)來(lái)指定。
以下是一些常用的驗(yàn)證器:
1. MaxValueValidator :驗(yàn)證最大值。
2. MinValueValidator :驗(yàn)證最小值。
3. MinLengthValidator :驗(yàn)證最小長(zhǎng)度。
4. MaxLengthValidator :驗(yàn)證最大長(zhǎng)度。
5. EmailValidator :驗(yàn)證是否是郵箱格式。
6. URLValidator :驗(yàn)證是否是 URL 格式。
7. RegexValidator :如果還需要更加復(fù)雜的驗(yàn)證,那么我們可以通過(guò)正則表達(dá)式的驗(yàn)證
器: RegexValidator 。比如現(xiàn)在要驗(yàn)證手機(jī)號(hào)碼是否合格,那么我們可以通過(guò)以下代碼實(shí)
現(xiàn):
class MyForm(forms.Form):
telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請(qǐng)輸入正確格式的手機(jī)號(hào)碼!')])
自定義驗(yàn)證:
有時(shí)候?qū)σ粋€(gè)字段驗(yàn)證,不是一個(gè)長(zhǎng)度,一個(gè)正則表達(dá)式能夠?qū)懬宄模€需要一些其他復(fù)雜的邏輯,那么我們可以對(duì)某個(gè)字段,進(jìn)行自定義的驗(yàn)證。比如在注冊(cè)的表單驗(yàn)證中,我們想要驗(yàn)證手機(jī)號(hào)碼是否已經(jīng)被注冊(cè)過(guò)了,那么這時(shí)候就需要在數(shù)據(jù)庫(kù)中進(jìn)行判斷才知道。對(duì)某個(gè)字段進(jìn)行自定義的驗(yàn)證方式是,定義一個(gè)方法,這個(gè)方法的名字定義規(guī)則是: clean_fieldname 。如果驗(yàn)證失敗,那么就拋出一個(gè)驗(yàn)證錯(cuò)誤。比如要驗(yàn)證用戶表中手機(jī)號(hào)碼之前是否在數(shù)據(jù)庫(kù)中存在,那么可以通過(guò)以下代碼實(shí)現(xiàn):
class MyForm(forms.Form): telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請(qǐng)輸入正確格式的手機(jī)號(hào)碼!')]) def clean_telephone(self): telephone = self.cleaned_data.get('telephone') exists = User.objects.filter(telephone=telephone).exists() if exists: raise forms.ValidationError("手機(jī)號(hào)碼已經(jīng)存在!") else: return telephone
以上是對(duì)某個(gè)字段進(jìn)行驗(yàn)證,如果驗(yàn)證數(shù)據(jù)的時(shí)候,需要針對(duì)多個(gè)字段進(jìn)行驗(yàn)證,那么可以重寫 clean 方法。比如要在注冊(cè)的時(shí)候,要判斷提交的兩個(gè)密碼是否相等。那么可以使用以下代碼來(lái)完成:
class MyForm(forms.Form): telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請(qǐng)輸入正確格式的手機(jī)號(hào)碼!')]) 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('兩個(gè)密碼不一致!')
提取錯(cuò)誤信息:
如果驗(yàn)證失敗了,那么有一些錯(cuò)誤信息是我們需要傳給前端的。這時(shí)候我們可以通過(guò)以下屬性來(lái)獲?。?/p>
1. form.errors :這個(gè)屬性獲取的錯(cuò)誤信息是一個(gè)包含了 html 標(biāo)簽的錯(cuò)誤信息。
2. form.errors.get_json_data() :這個(gè)方法獲取到的是一個(gè)字典類型的錯(cuò)誤信息。將某個(gè)字段的名字作為 key ,錯(cuò)誤信息作為值的一個(gè)字典。
3. form.as_json() :這個(gè)方法是將 form.get_json_data() 返回的字典 dump 成 json 格式的字符串,方便進(jìn)行傳輸。
4. 上述方法獲取的字段的錯(cuò)誤值,都是一個(gè)比較復(fù)雜的數(shù)據(jù)。比如以下:
{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensurethis value has at most 4 characters (it has 22).', 'code': 'max_length'}]}
那么如果我只想把錯(cuò)誤信息放在一個(gè)列表中,而不要再放在一個(gè)字典中。這時(shí)候我們可以定義一個(gè)方法,把這個(gè)數(shù)據(jù)重新整理一份。實(shí)例代碼如下:
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
這樣就可以把某個(gè)字段所有的錯(cuò)誤信息直接放在這個(gè)列表中。
以上這篇Django def clean()函數(shù)對(duì)表單中的數(shù)據(jù)進(jìn)行驗(yàn)證操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Django表單外鍵選項(xiàng)初始化的問(wèn)題及解決方法
- django表單中的按鈕獲取數(shù)據(jù)的實(shí)例分析
- Django 構(gòu)建模板form表單的兩種方法
- Django form表單與請(qǐng)求的生命周期步驟詳解
- Django model.py表單設(shè)置默認(rèn)值允許為空的操作
- Django表單提交后實(shí)現(xiàn)獲取相同name的不同value值
- Django框架獲取form表單數(shù)據(jù)方式總結(jié)
- django之從html頁(yè)面表單獲取輸入的數(shù)據(jù)實(shí)例
- 解決django中form表單設(shè)置action后無(wú)法回到原頁(yè)面的問(wèn)題
- django-xadmin根據(jù)當(dāng)前登錄用戶動(dòng)態(tài)設(shè)置表單字段默認(rèn)值方式
- Django給表單添加honeypot驗(yàn)證增加安全性
相關(guān)文章
使用Flask-Login模塊實(shí)現(xiàn)用戶身份驗(yàn)證和安全性
當(dāng)你想要在你的Flask應(yīng)用中實(shí)現(xiàn)用戶身份驗(yàn)證和安全性時(shí),F(xiàn)lask-Login這個(gè)擴(kuò)展將會(huì)是你的最佳伙伴,它提供了一組簡(jiǎn)單而強(qiáng)大的工具來(lái)處理,下面我們就來(lái)看看具體的操作方法吧2023-08-08Python3日期與時(shí)間戳轉(zhuǎn)換的幾種方法詳解
我們可以利用內(nèi)置模塊 datetime 獲取當(dāng)前時(shí)間,然后將其轉(zhuǎn)換為對(duì)應(yīng)的時(shí)間戳。這篇文章主要介紹了Python3日期與時(shí)間戳轉(zhuǎn)換的幾種方法,需要的朋友可以參考下2019-06-06Python使用pyyaml模塊處理yaml數(shù)據(jù)
這篇文章主要介紹了Python使用pyyaml模塊處理yaml數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04關(guān)于jieba.cut與jieba.lcut的區(qū)別及說(shuō)明
這篇文章主要介紹了關(guān)于jieba.cut與jieba.lcut的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05python-opencv 中值濾波{cv2.medianBlur(src, ksize)}的用法
這篇文章主要介紹了python-opencv 中值濾波{cv2.medianBlur(src, ksize)}的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2021-06-06python 服務(wù)器運(yùn)行代碼報(bào)錯(cuò)ModuleNotFoundError的解決辦法
這篇文章主要介紹了python 服務(wù)器運(yùn)行代碼報(bào)錯(cuò)ModuleNotFoundError的解決辦法,幫助大家排除錯(cuò)誤,正確的運(yùn)行代碼,感興趣的朋友可以了解下2020-09-09Python OOP類中的幾種函數(shù)或方法總結(jié)
今天小編就為大家分享一篇關(guān)于Python OOP類中的幾種函數(shù)或方法總結(jié),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02python實(shí)現(xiàn)opencv+scoket網(wǎng)絡(luò)實(shí)時(shí)圖傳
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)opencv+scoket網(wǎng)絡(luò)實(shí)時(shí)圖傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03