1. 程式人生 > >Django模型驗證器詳解和原始碼分析

Django模型驗證器詳解和原始碼分析

### 轉發請註明來源 在Django的模型欄位引數中,有一個引數叫做`validators`,這個引數是用來指定當前欄位需要使用的驗證器,也就是對欄位資料的合法性進行驗證,比如大小、型別等。 Django的驗證器可以分為模型相關的驗證器和表單相關的驗證器,它們基本類似,但在使用上有區別。 **本文討論的是模型相關的驗證器。** ## 一、自定義驗證器 一個驗證器其實就是一個可呼叫的物件(函式或類),接收一個初始輸入值作為引數,對這個值進行一系列邏輯判斷,如果不滿足某些規則或者條件,則表示驗證不通過,丟擲一個`ValidationError`異常。如果滿足條件則通過驗證,不返回任何內容(也就是預設的return None),可以繼續下一步。 驗證器具有重要作用,可以被重用在別的欄位上,是工具型別的邏輯封裝。 下面是一個驗證器的例子,它只允許偶數通過驗證: ```python from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ def validate_even(value): if value % 2 != 0: raise ValidationError( _('%(value)s is not an even number'), params={'value': value}, ) ``` 通過下面的方式,將偶數驗證器應用在欄位上: ```python from django.db import models class MyModel(models.Model): even_field = models.IntegerField(validators=[validate_even]) ``` 因為驗證器執行之前,(輸入的)資料會被轉換為 Python 物件,因此我們可以將同樣的驗證器用在 Django form 表單中(事實上Django為表單提供了另外一些驗證器): ```python from django import forms class MyForm(forms.Form): even_field = forms.IntegerField(validators=[validate_even]) ``` 你還可以通過Python的魔法方法`__cal__()`編寫更復雜的可配置的驗證器,比如Django內建的`RegexValidator`驗證器就是這麼幹的。 驗證器也可以是一個類,但這時候就比較複雜了,需要確保它可以被遷移框架序列化,確保編寫了`deconstruction()`和`__eq__()`方法。*這種做法很難找到參考文獻和博文,要靠自己摸索或者研究DJango原始碼。* ## 二、工作機制 讓我們來測試一下上面寫的驗證器: ```python >>> from .models import MyModel >>> a = MyModel.objects.create(even_field=3) >>