国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Django筆記四十二之model使用validator驗(yàn)證器

這篇具有很好參考價(jià)值的文章主要介紹了Django筆記四十二之model使用validator驗(yàn)證器。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本文首發(fā)于公眾號:Hunter后端

原文鏈接:Django筆記四十二之model使用validator驗(yàn)證器

這一篇筆記介紹一下 model 里的 validator 驗(yàn)證器。

首先,這是個(gè)什么東西呢?

在 model 的第四篇筆記里,我們介紹了字段的一些屬性,比如是否允許為空,varchar 類型的字段的最大長度等。

一般在存儲前,我們要手動對數(shù)據(jù)進(jìn)行一些校驗(yàn),比如判斷前端傳入的字段是否為空,傳入的字符最大長度是否超過我們規(guī)定的長度等。

而 validator 驗(yàn)證器就給我們提供了一個(gè)簡便的方式可以在存儲數(shù)據(jù)前自動進(jìn)行校驗(yàn)。

以下是本篇筆記目錄:

  1. 自定義驗(yàn)證器
  2. 引用驗(yàn)證器
  3. 校驗(yàn)函數(shù)
  4. 測試校驗(yàn)函數(shù)
  5. 系統(tǒng)驗(yàn)證器介紹

1、自定義驗(yàn)證器

我們下面會在 model 中調(diào)用一個(gè)驗(yàn)證器,它的作用是只允許保存偶數(shù),如果是奇數(shù)則會引發(fā) ValidationError。

示例如下:

from django.core.exceptions import ValidationError

def validate_even(value):
    if value % 2 != 0:
        raise ValidationError(f"{value} is not an even number")

如上所示,一個(gè)簡單的驗(yàn)證器就完成了,它是一個(gè)函數(shù),我們可以手動調(diào)用,傳入奇數(shù)或者偶數(shù)嘗試,傳入偶數(shù)不會發(fā)生什么,但是傳入奇數(shù)則會引發(fā)一個(gè) ValidationError 的報(bào)錯(cuò)。

2、引用驗(yàn)證器

定義好一個(gè)驗(yàn)證器之后,我們在 model 中引入。

我們這里新建一個(gè) model,名為 TestValidate:

class TestValidate(models.Model):
    even_field = models.IntegerField(default=0, validators=[validate_even])

如上,一個(gè)驗(yàn)證器的引入就完成了,當(dāng)我們在嘗試對數(shù)據(jù)進(jìn)行保存的時(shí)候,比如創(chuàng)建一條數(shù)據(jù):

TestValidate.objects.create(even_field=1)

傳入的數(shù)據(jù)值為 1,是不合法的,但是卻可以保存,為什么呢?

這里介紹一下觸發(fā)驗(yàn)證器的機(jī)制。

雖然我們在 model 里引入了驗(yàn)證器,但是 Django 系統(tǒng)并不會自動觸發(fā),而需要我們進(jìn)行手動去觸發(fā)校驗(yàn)操作。

我們在下一節(jié)介紹一下進(jìn)行校驗(yàn)的四個(gè)函數(shù):

  1. clean_fields()
  2. clean()
  3. validate_unique()
  4. full_clean()

3、校驗(yàn)函數(shù)

前面介紹到需要在保存前手動調(diào)用校驗(yàn)函數(shù),先介紹一下四個(gè)校驗(yàn)函數(shù)

1.clean_fields(exclude=None)

接收 exclude 參數(shù),參數(shù)類型為列表,列表元素為字段名稱,表示傳入的字段不進(jìn)行校驗(yàn),如果不傳該參數(shù),則默認(rèn)對 model 的所有字段進(jìn)行校驗(yàn)。

這個(gè)函數(shù)的操作是,校驗(yàn) model 里中所有不合法的字段數(shù)據(jù),比如沒有設(shè)置允許為空,但字段的值為空,以及包括設(shè)置了 validators 參數(shù)的字段。

比如前面我們設(shè)置了 even_field 字段只允許保存偶數(shù),那么在 save() 操作前,調(diào)用 clean_fields() 函數(shù),則會引發(fā) validate_even 的報(bào)錯(cuò)。

2.clean()

默認(rèn)是一個(gè)空函數(shù),用于我們繼承重寫一些校驗(yàn)操作,我們可以自定義一些 model 的限制需求,比如,它可以進(jìn)行不同字段間的關(guān)聯(lián)校驗(yàn)

3.validate_unique(exclude=None)

驗(yàn)證的是字段數(shù)據(jù)是否違反唯一性約束,其實(shí)也就是獲取 model 里所有包含唯一性約束的字段,然后去數(shù)據(jù)庫里查詢是否包含同樣的數(shù)據(jù),如果存在,則引發(fā)驗(yàn)證報(bào)錯(cuò)。

唯一性約束包含 unique,unique_for_date,unique_for_year,unique_for_month 等,接收 exclude 參數(shù),和 clean_fields() 函數(shù)一致,exclude 為不進(jìn)行校驗(yàn)的字段

4.full_clean(exclude=None, validate_unique=True)

所以我們在進(jìn)行 model 的 save() 操作前,可以根據(jù)我們的需要進(jìn)行相應(yīng)的校驗(yàn)操作

也可以直接調(diào)用 full_clean() 函數(shù),這個(gè)函數(shù)會依次調(diào)用 clean_fields,clean,和 validate_unique 函數(shù)。

full_clean() 接收兩個(gè)參數(shù),一個(gè) exclude,接收不校驗(yàn)的字段列表,一個(gè)validate_unique,為布爾型數(shù)據(jù),表示是否需要進(jìn)行唯一性校驗(yàn)

4、測試校驗(yàn)函數(shù)

下面我們挨個(gè)對校驗(yàn)函數(shù)進(jìn)行處理測試操作。

首先重新設(shè)置一下 model:

# blog/models.py

from django.core.exceptions import ValidationError
from django.db import models


def validate_even(value):
    if value % 2 != 0:
        raise ValidationError(f"{value} is not an even number")


class TestValidate(models.Model):
    even_field = models.IntegerField(default=0, validators=[validate_even])
    name = models.CharField(unique=True, max_length=20, default=None)

1. 測試clean_fields

測試這個(gè)函數(shù),我們只需要在給實(shí)例化后的 model 調(diào)用這個(gè)函數(shù)即可:

test_1 = TestValidate.objects.create(even_field=2, name="abc")

test_2 = TestValidate()
test_2.even_field = 1
test_2.name = "abc"
test_2.clean_fields()

在 test_2 調(diào)用 clean_fields() 后,系統(tǒng)會校驗(yàn) TestValidate 實(shí)例化后所有字段的的不合法數(shù)據(jù),以及額外的校驗(yàn)操作,即 validators 中定義的校驗(yàn)邏輯

比如在這里 even_field = 1 會被驗(yàn)證不通過,返回一個(gè)報(bào)錯(cuò)

clean_fields() 函數(shù)可以接收 exclude 參數(shù),可用于傳入不進(jìn)行校驗(yàn)的字段名稱列表,比如這里我們設(shè)置:

test_2.clean_fields(exclude=["even_field"])

那么即便 even_field 的字段值不合法,也會順利保存。

2. 測試validate_unique

在這里我們設(shè)置了 name 字段為 unique 唯一性約束,也就是說在 TestValidate 表里 name 字段不能存在相同的值

前面我們創(chuàng)建了一條 name = "abc" 的值,接著我們設(shè)置 test_2.name = "abc",然后執(zhí)行:

test_2.name = "abc"
test_2.validate_unique()

系統(tǒng)會獲取 TestValidate 里所有設(shè)置了 unique 的字段,然后獲取字段對應(yīng)的值去數(shù)據(jù)庫進(jìn)行唯一性校驗(yàn),在我們上面的例子里設(shè)置 name="abc" 是不通過的。

3. 測試clean

系統(tǒng)提供了 clean() 函數(shù),可用于我們創(chuàng)建自定義的驗(yàn)證操作

比如,我們設(shè)置當(dāng) even_field = 4 且 name="張三" 的時(shí)候,這條數(shù)據(jù)就是不合法的,我們可以如此先設(shè)置 clean() 函數(shù):

class TestValidate(models.Model):
    even_field = models.IntegerField(default=0, validators=[validate_even])
    name = models.CharField(unique=True, max_length=20, default=None)


    def clean(self):
        if self.even_field == 4 and self.name == "張三":
            raise ValidationError("指定 even_field 和 name 不合法")

再執(zhí)行:

from blog.models import TestValidate

test_3 = TestValidate()
test_3.even_field = 4
test_3.name = "張三"
test_3.clean()

4. 測試full_clean

如果我們想在 save() 前都調(diào)用一遍上面介紹的校驗(yàn)函數(shù),可以直接執(zhí)行 full_clean(),它會按照順序挨個(gè)調(diào)用 clean_fields、clean、validate_unique

full_clean() 接收兩個(gè)參數(shù),一個(gè) exclude,接收不校驗(yàn)的字段列表,一個(gè)validate_unique,為 布爾型數(shù)據(jù),確定是否需要進(jìn)行唯一性校驗(yàn)

5. 重寫save()

前面我們會在每次進(jìn)行 save() 前都手動執(zhí)行校驗(yàn)函數(shù),我們可以重寫 save(),這樣在每次創(chuàng)建和保存一個(gè) model 實(shí)例的時(shí)候,就不需要手動調(diào)用我們前面的校驗(yàn)函數(shù)了,操作示例如下:

class TestValidate(models.Model):
    even_field = models.IntegerField(default=0, validators=[validate_even])
    name = models.CharField(unique=True, max_length=20, default=None)


    def save(self, *args, **kwargs):
        self.clean_fields()
        self.clean()
        self.validate_unique()
        super(TestValidate, self).save(*args, **kwargs)

而 full_clean() 可以直接調(diào)用這三個(gè)校驗(yàn)函數(shù),所以上面等效于:

def save(self, *args, **kwargs):
    self.full_clean()
    super(TestValidate, self).save(*args, **kwargs)

清空表數(shù)據(jù)后,我們可以進(jìn)行下面的測試:

from blog.models import TestValidate

test_1 = TestValidate.objects.create(even_field=2, name="abc")

test_2 = TestValidate.objects.create(even_field=2, name="abc")  # 會報(bào)校驗(yàn)的錯(cuò)誤

test_3 = TestValidate()
test_3.even_field=3
test_3.name = "def"
test_3.save()  # 報(bào)校驗(yàn)的錯(cuò)誤

6. 繼承BaseModel

我們上面的操作是基于單個(gè) model 的 save() 操作,如果我們要對每個(gè) model 都實(shí)現(xiàn)這種自動進(jìn)行校驗(yàn)的操作,那么則需要對每個(gè) model 都進(jìn)行這種 save() 的繼承重寫操作

如果想要實(shí)現(xiàn)每個(gè) model 自動實(shí)現(xiàn)這種校驗(yàn)的操作,我們可以編寫一個(gè) BaseModel,在 BaseModel 里重寫 save() 操作,然后每個(gè) model 都繼承 BaseModel,就可以實(shí)現(xiàn)我們的目的了。

class BaseModel(models.Model):

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        self.full_clean()
        super(BaseModel, self).save(*args, **kwargs)


class TestValidate(BaseModel):
    even_field = models.IntegerField(default=0, validators=[validate_even])
    name = models.CharField(unique=True, max_length=20, default=None)

這種操作也可以用于添加基礎(chǔ)字段,比如我們想為每個(gè) model 都添加 updated_time 和 created_time 作為基礎(chǔ)字段,用于記錄數(shù)據(jù)寫入和更新時(shí)間,可以在 BaseModel 里添加:

class BaseModel(models.Model):
    
    updated_time = models.DateTimeField(auto_now=True)
    created_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True    

    def save(self, *args, **kwargs):
        self.full_clean()
        super(BaseModel, self).save(*args, **kwargs)

5、系統(tǒng)驗(yàn)證器介紹

前面介紹的是自定義的驗(yàn)證器,以及如何使用,其實(shí)Django系統(tǒng)里為我們實(shí)現(xiàn)了很多基礎(chǔ)的驗(yàn)證器:

  • EmailValidator 驗(yàn)證郵箱格式
  • MaxValueValidator 驗(yàn)證最大值
  • MinValueValidator 驗(yàn)證最小值
  • MaxLengthValidator 驗(yàn)證最大長度
  • MinLengthValidator 驗(yàn)證最小長度
  • RegexValidator 驗(yàn)證正則表達(dá)式

我們設(shè)置的 model 如下:

class TestValidate(BaseModel):
    even_field = models.IntegerField(default=0, validators=[validate_even])
    name = models.CharField(unique=True, max_length=20, default=None)
    email = models.CharField(max_length=100, default="", validators=[EmailValidator(message="email不合法")])
    count = models.IntegerField(default=8, validators=[MaxValueValidator(limit_value=20), MinValueValidator(limit_value=5)])
    char_str = models.CharField(max_length=100, validators=[MaxLengthValidator(limit_value=90), MinLengthValidator(limit_value=20)], default="")
    telephone = models.CharField(max_length=11, validators=[RegexValidator("1[345678]\d{9}")], default="")

用上了上面這幾個(gè)自帶的驗(yàn)證器,接下來我們對 email,count,char_str,telephone 幾個(gè)字段設(shè)置不合法的值進(jìn)行創(chuàng)建:

TestValidate.objects.create(
    even_field=2,
    name="abc",
    email="12314234",
    count=25,
    char_str="abcd",
    telephone="122282883"
)

然后會發(fā)現(xiàn)從 email 到 telephone 字段都報(bào)了字段值不合法的錯(cuò),我們將其挨個(gè)修正為 model 里符合校驗(yàn)規(guī)則的數(shù)據(jù)即可正常創(chuàng)建數(shù)據(jù)了。

如果想獲取更多相關(guān)文章,可掃碼關(guān)注閱讀:

Django筆記四十二之model使用validator驗(yàn)證器文章來源地址http://www.zghlxwxcb.cn/news/detail-746753.html

到了這里,關(guān)于Django筆記四十二之model使用validator驗(yàn)證器的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Django筆記四十三之使用uWSGI部署Django系統(tǒng)

    Django筆記四十三之使用uWSGI部署Django系統(tǒng)

    本文首發(fā)于公眾號:Hunter后端 原文鏈接:Django筆記四十三之使用uWSGI部署Django系統(tǒng) 目前部署 Django 的方式一般來說是使用 Nginx + uWSGI + Django 來實(shí)現(xiàn)。 處理流程是,當(dāng)一個(gè)請求發(fā)送過來會先經(jīng)過 Nginx,如果是靜態(tài)文件請求,Nginx 這一層直接處理,如果是后端動態(tài)接口,則會發(fā)送

    2024年02月05日
    瀏覽(25)
  • Django筆記四十之運(yùn)行Django環(huán)境的python腳本

    Django筆記四十之運(yùn)行Django環(huán)境的python腳本

    本文首發(fā)于公眾號:Hunter后端 原文鏈接:Django筆記四十之運(yùn)行Django環(huán)境的python腳本 這一篇筆記介紹如何在 Django 中運(yùn)行腳本。 假設(shè)說我們要實(shí)現(xiàn)一個(gè)功能,需要獲取 blog.models.Blog 這張表里的總數(shù)且使用 print() 輸出。 如果代碼邏輯很短,且是一次性執(zhí)行的操作,我們可以在系

    2024年02月04日
    瀏覽(16)
  • Django筆記四十四之Nginx+uWSGI部署Django以及Nginx負(fù)載均衡操作

    Django筆記四十四之Nginx+uWSGI部署Django以及Nginx負(fù)載均衡操作

    本文首發(fā)于公眾號:Hunter后端 原文鏈接:Django筆記四十四之Nginx+uWSGI部署Django以及Nginx負(fù)載均衡操作 這一篇筆記介紹如何使用 Nginx + uWSGI 來部署 Django。 上一篇筆記中有介紹直接使用 uWSGI 作為 web 服務(wù)器來部署 Django,這一篇筆記介紹如何使用 Nginx 來部署。 使用 Nginx 來部署相

    2024年02月05日
    瀏覽(27)
  • 【微信小程序】-- 使用 npm 包 - API Promise化(四十二)

    【微信小程序】-- 使用 npm 包 - API Promise化(四十二)

    ?? 所屬專欄:【微信小程序開發(fā)教程】 ?? 作??者:我是夜闌的狗?? ?? 個(gè)人簡介:一個(gè)正在努力學(xué)技術(shù)的CV工程師,專注基礎(chǔ)和實(shí)戰(zhàn)分享 ,歡迎咨詢! ?? 歡迎大家:這里是CSDN,我總結(jié)知識的地方,喜歡的話請三連,有問題請私信 ?? ?? ?? ??大家好,又見面了,

    2023年04月09日
    瀏覽(16)
  • Django筆記(五):模型models

    Django中的模型對應(yīng)數(shù)據(jù)庫中的一張表格。 player.py 每個(gè)模型需要繼承models類,如上Player模型定義了一個(gè)整形字段idx。常見字段類型有: 字段 描述 IntegerField 整形 FloatField 浮點(diǎn)型 CharField 字符串類型 TextField 長文本類型 BooleanField 布爾類型 每個(gè)字段可定義參數(shù): 參數(shù) 取值 描述

    2024年01月22日
    瀏覽(10)
  • django中的model的一些筆記

    model中外鍵關(guān)聯(lián)中的related_name屬性,可以在外鍵表中作為篩選條件,也就是反過來在外鍵表中使用。例如下面的使用WarehouseStockRecord就是外鍵表 2.django中的Q()對象用于構(gòu)建復(fù)雜查詢條件的工具 在查詢時(shí),可以將Q對象作為參數(shù)傳遞給filter()方法,以實(shí)現(xiàn)復(fù)雜的查詢條件

    2024年02月16日
    瀏覽(16)
  • Python筆記二之多線程

    Python筆記二之多線程

    本文首發(fā)于公眾號:Hunter后端 原文鏈接:Python筆記二之多線程 這一篇筆記介紹一下在 Python 中使用多線程。 注意 :以下的操作都是在 Python 3.8 版本中試驗(yàn),不同版本可能有不同之處,需要注意。 本篇筆記目錄如下: 概念 多線程的使用示例 daemon run() 線程對象的屬性和設(shè)置

    2024年02月03日
    瀏覽(16)
  • es 筆記二之基礎(chǔ)查詢

    es 筆記二之基礎(chǔ)查詢

    本文首發(fā)于公眾號:Hunter后端 原文鏈接:es筆記二之基礎(chǔ)查詢 這一篇筆記介紹 es 的基礎(chǔ)查詢。 基礎(chǔ)查詢包括很多,比如排序,類似數(shù)據(jù)庫 limit 的操作,like 操作,與或非等,對于這些操作,我會在介紹他們的用法之后加上對應(yīng)的數(shù)據(jù)庫 sql 便于理解。 注意: 下面的操作都在

    2024年02月05日
    瀏覽(12)
  • 第四十二回:DateRangePickerDialog Widget

    我們在上一章回中介紹了DatePickerDialog Widget相關(guān)的內(nèi)容,本章回中將介紹 DateRangePickerDialog Widget .閑話休提,讓我們一起Talk Flutter吧。 我們在這里說的 DateRangePickerDialog 是一種彈出窗口,只不過窗口的內(nèi)容固定顯示為日期,它和DatePickerDialog類似,也是用來讓用戶選擇日期,選擇

    2024年02月07日
    瀏覽(87)
  • Mariadb高可用MHA (四十二)

    Mariadb高可用MHA (四十二)

    提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 目錄 前言 一、概述?? ? 1.1 概念 ?1.2 組成 ? 1.3? 特點(diǎn) ? 1.4? 工作原理 二、構(gòu)建MHA 2.1 ssh免密登錄 2.2 主從復(fù)制 2.3 MHA安裝? 2.3.1所有節(jié)點(diǎn)安裝perl環(huán)境 2.3..2 node 2.3.3 manager?(只在mgt上裝) 2.3.4 測試 2.

    2024年02月12日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包