最淺顯易懂的Django系列教程(35)-用表單驗(yàn)證數(shù)據(jù)

用表單驗(yàn)證數(shù)據(jù)

常用的Field:

使用Field可以是對(duì)數(shù)據(jù)驗(yàn)證的第一步茸俭。你期望這個(gè)提交上來(lái)的數(shù)據(jù)是什么類型狠持,那么就使用什么類型的Field合是。

CharField:

用來(lái)接收文本火窒。
參數(shù):

  • max_length:這個(gè)字段值的最大長(zhǎng)度甚垦。
  • min_length:這個(gè)字段值的最小長(zhǎng)度届垫。
  • required:這個(gè)字段是否是必須的释液。默認(rèn)是必須的。
  • error_messages:在某個(gè)條件驗(yàn)證失敗的時(shí)候装处,給出錯(cuò)誤信息误债。

EmailField:

用來(lái)接收郵件,會(huì)自動(dòng)驗(yàn)證郵件是否合法。
錯(cuò)誤信息的key:required寝蹈、invalid李命。

FloatField:

用來(lái)接收浮點(diǎn)類型,并且如果驗(yàn)證通過(guò)后箫老,會(huì)將這個(gè)字段的值轉(zhuǎn)換為浮點(diǎn)類型封字。
參數(shù):

  • max_value:最大的值。
  • min_value:最小的值槽惫。

錯(cuò)誤信息的key:required周叮、invalidmax_value界斜、min_value仿耽。

IntegerField:

用來(lái)接收整形,并且驗(yàn)證通過(guò)后各薇,會(huì)將這個(gè)字段的值轉(zhuǎn)換為整形项贺。
參數(shù):

  • max_value:最大的值。
  • min_value:最小的值峭判。

錯(cuò)誤信息的key:required开缎、invalidmax_value林螃、min_value奕删。

URLField:

用來(lái)接收url格式的字符串。
錯(cuò)誤信息的key:required疗认、invalid完残。


常用驗(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)存在九巡!")
        return telephone

以上是對(duì)某個(gè)字段進(jìn)行驗(yàn)證,如果驗(yàn)證數(shù)據(jù)的時(shí)候蹂季,需要針對(duì)多個(gè)字段進(jìn)行驗(yàn)證冕广,那么可以重寫(xiě)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)獲群瘟摺:

  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()返回的字典dumpjson格式的字符串,方便進(jìn)行傳輸黔酥。
  4. 上述方法獲取的字段的錯(cuò)誤值藻三,都是一個(gè)比較復(fù)雜的數(shù)據(jù)洪橘。比如以下:
{'username': [{'message': 'Enter a valid URL.', 'code': 'invalid'}, {'message': 'Ensure this 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è)列表中逗概。

看文章不過(guò)癮弟晚?還有免費(fèi)的視頻教程,讓你學(xué)起來(lái)更輕松:https://www.zhiliaoketang.cn/course/detail/4.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逾苫,一起剝皮案震驚了整個(gè)濱河市卿城,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铅搓,老刑警劉巖瑟押,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異星掰,居然都是意外死亡勉耀,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)蹋偏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)便斥,“玉大人,你說(shuō)我怎么就攤上這事威始∈嗑溃” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵黎棠,是天一觀的道長(zhǎng)晋渺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)脓斩,這世上最難降的妖魔是什么木西? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮随静,結(jié)果婚禮上八千,老公的妹妹穿的比我還像新娘。我一直安慰自己燎猛,他們只是感情好恋捆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著重绷,像睡著了一般沸停。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上昭卓,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天愤钾,我揣著相機(jī)與錄音瘟滨,去河邊找鬼。 笑死能颁,一個(gè)胖子當(dāng)著我的面吹牛室奏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劲装,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼昌简!你這毒婦竟也來(lái)了占业?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纯赎,失蹤者是張志新(化名)和其女友劉穎谦疾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體犬金,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡念恍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晚顷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峰伙。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖该默,靈堂內(nèi)的尸體忽然破棺而出瞳氓,到底是詐尸還是另有隱情,我是刑警寧澤栓袖,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布匣摘,位于F島的核電站,受9級(jí)特大地震影響裹刮,放射性物質(zhì)發(fā)生泄漏音榜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一捧弃、第九天 我趴在偏房一處隱蔽的房頂上張望赠叼。 院中可真熱鬧,春花似錦违霞、人聲如沸梅割。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)户辞。三九已至,卻和暖如春癞谒,著一層夾襖步出監(jiān)牢的瞬間底燎,已是汗流浹背刃榨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留双仍,地道東北人枢希。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像朱沃,于是被迫代替她去往敵國(guó)和親苞轿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348