django Model層常用驗(yàn)證器及自定義驗(yàn)證器詳解
在Django中,對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)有兩種方式:一種是通過(guò)Form校驗(yàn),一種是通過(guò)Model校驗(yàn)。在此,我對(duì)Model中的校驗(yàn)方法做下記錄。
示例之前補(bǔ)充以下幾點(diǎn):
1、Django數(shù)據(jù)校驗(yàn)方式分為以下三步:
Model.clean_fields() 驗(yàn)證字段基本規(guī)則比如長(zhǎng)度格式等;
Model.clean() 可自定義驗(yàn)證條件和報(bào)錯(cuò)信息;
Model.validate_unique() 為驗(yàn)證添加的唯一性約束。
2、此三步驗(yàn)證通過(guò)調(diào)用full_claen(exclude=None, validate_unique=True)來(lái)依次執(zhí)行。
exclude:可以用來(lái)指定不需要執(zhí)行校驗(yàn)的field。ModelForm也利用這個(gè)參數(shù)來(lái)將field排除。
validate_unique:用來(lái)指定是否需要執(zhí)行Model.validate_unique()。
3、而full_clean()又是通過(guò)調(diào)用is_valid()方法來(lái)執(zhí)行。
4、save()執(zhí)行的時(shí)候是不會(huì)自動(dòng)調(diào)用full_clean()來(lái)進(jìn)行校驗(yàn)的。
校驗(yàn)應(yīng)該在save()執(zhí)行之前完成,你可以先在form進(jìn)行校驗(yàn),也可以在model中進(jìn)行校驗(yàn)。但是,你必須確保通過(guò)這兩個(gè)校驗(yàn)之后的數(shù)據(jù)是絕對(duì)沒(méi)有問(wèn)題的“干凈”數(shù)據(jù),然后再調(diào)用save()方法將數(shù)據(jù)存儲(chǔ)入庫(kù)。
5、校驗(yàn)中的錯(cuò)誤處理
我們使用ValidationError來(lái)在Model.clean中拋出錯(cuò)誤,這個(gè)錯(cuò)誤信息將會(huì)存儲(chǔ)在以NON_FIELD_ERRORS為key的字典中。這個(gè)key是用來(lái)存儲(chǔ)對(duì)于整個(gè)model中的錯(cuò)誤信息的。
如何獲取校驗(yàn)的錯(cuò)誤信息:
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS try: article.full_clean() except ValidationError as e: non_field_errors = e.message_dict[NON_FIELD_ERRORS]
如何指定對(duì)于某個(gè)特定的field的校驗(yàn)錯(cuò)誤信息:
class Article(models.Model): ... def clean(self): if self.status == 'draft' and self.pub_date is not None: # raise ValidationError({'pub_date': _('Draft entries may not have a publication date.')}) raise ValidationError({'pub_date': 'Draft entries may not have a publication date.'}) ...
如何指定多個(gè)field的校驗(yàn)錯(cuò)誤信息:
class Article(models.Model): ... def clean(self): if self.status == 'draft' and self.pub_date is not None: raise ValidationError({'pub_date': 'Draft entries may not have a publication date.', 'creator': 'Creator can't be null'}) ...
如何指定全局性校驗(yàn)錯(cuò)誤信息:
class Article(models.Model): ... def clean(self): if self.status == 'draft' and self.pub_date is not None: raise ValidationError('Draft entries may not have a publication date.') ...
進(jìn)入正題:
一、如何使用驗(yàn)證器:
在驗(yàn)證某個(gè)字段的時(shí)候,在模型或者自定義form表單中傳遞一個(gè) validators 參數(shù)用來(lái)指定驗(yàn)證器,進(jìn)一步對(duì)數(shù)據(jù)進(jìn)行過(guò)濾。
或者,通過(guò)model中的 Field類型 或者一些參數(shù)就可以指定。
比如 EmailValidator ,我們可以通過(guò) 指定字段類型為EmailField 來(lái)指定。
比如 MaxValueValidator ,我們可以通過(guò) max_value 、max_length參數(shù)來(lái)指定。
class Interview(models.Model): feedback = models.TextField(max_length=1024, validators=[MinLengthValidator(20, message='不少于20字')], verbose_name='面試反饋') mail = models.EmailField(max_length=64, blank=True, null=True, verbose_name='郵箱') age= models.IntegerField(max_value=64, blank=True, null=True, verbose_name='年齡')
二、常用自帶驗(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)證。
class Demo(models.Model): telephone = models.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='請(qǐng)輸入正確格式的手機(jī)號(hào)碼!')])
三、自定義驗(yàn)證器:
方法:
如果你想要自定義model的校驗(yàn),或者想要修改model的屬性的話,就要重寫clean()方法。
class Interview(models.Model): feedback = models.TextField(max_length=1024, validators=[MinLengthValidator(20, message='不少于20字')], verbose_name='面試反饋') mail = models.EmailField(max_length=64, blank=True, null=True, verbose_name='郵箱') age= models.IntegerField(max_value=64, blank=True, null=True, verbose_name='年齡' ... def clean(self): if self.result_1 == InterviewResult.FAIL and len(self.feedback) < 20: raise ValidationError({'feedback': '不少于20字'})
效果:
如果你想做一個(gè)全局性的錯(cuò)誤提示,可以這樣:
... def clean(self): if self.result_1 == InterviewResult.FAIL and len(self.feedback) < 20: raise ValidationError('不少于20字吧')
效果:
以上這篇django Model層常用驗(yàn)證器及自定義驗(yàn)證器詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python高階函數(shù)functools模塊的具體使用
本文主要介紹了python高階函數(shù)functools模塊的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Pycharm中運(yùn)行程序在Python?console中執(zhí)行,不是直接Run問(wèn)題
這篇文章主要介紹了Pycharm中運(yùn)行程序在Python?console中執(zhí)行,不是直接Run問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07python 使用OpenCV進(jìn)行簡(jiǎn)單的人像分割與合成
這篇文章主要介紹了python 使用OpenCV進(jìn)行簡(jiǎn)單的人像分割與合成的方法,幫助大家更好的利用python處理圖像,感興趣的朋友可以了解下2021-02-02pytest使用@pytest.mark.parametrize()實(shí)現(xiàn)參數(shù)化的示例代碼
這篇文章主要介紹了pytest使用@pytest.mark.parametrize()實(shí)現(xiàn)參數(shù)化,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07python使用梯度下降和牛頓法尋找Rosenbrock函數(shù)最小值實(shí)例
這篇文章主要介紹了python使用梯度下降和牛頓法尋找Rosenbrock函數(shù)最小值實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Python求解排列中的逆序數(shù)個(gè)數(shù)實(shí)例
這篇文章主要介紹了Python求解排列中的逆序數(shù)個(gè)數(shù)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05python實(shí)現(xiàn)的簡(jiǎn)單窗口倒計(jì)時(shí)界面實(shí)例
這篇文章主要介紹了python實(shí)現(xiàn)的簡(jiǎn)單窗口倒計(jì)時(shí)界面,實(shí)例分析了Python基于Tkinter操作windows窗口界面的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05