反序列化過程中,除了校驗字段類型和長度大小之外,還需要有其它的條件限制的校驗,這時我們可以使用validators自定義校驗項
一、唯一字段校驗
1.引入validators模塊
from rest_framework import validators
2.在需要唯一校驗的字段類里面設置validators字段的屬性,值為一個列表,在列表里面添加唯一校驗UniqueValidator,除了UniqueValidator的唯一校驗,還有其它的唯一校驗,根據不同的場景選擇使用即可
唯一校驗UniqueValidator類一般接收兩個參數,一個是queryset,需要傳一個查詢集,一個是message,為自定義的異常校驗信息,代碼如下:
from rest_framework import serializers from rest_framework import validators from .models import Projects class ProjectSerializer(serializers.Serializer): name = serializers.CharField(max_length=200, label="項目名稱", help_text='項目名稱', validators=[validators.UniqueValidator(queryset=Projects.objects.all(), message="項目名字段name必須唯一")]) leader = serializers.CharField(max_length=50, label="項目負責人", help_text='項目負責人') programmer = serializers.CharField(max_length=50, label="開發人員", help_text="開發人員") tester = serializers.CharField(max_length=50, label="測試人員", help_text="測試人員")
驗證結果:
二、自定義校驗器函數
假設我們規定name字段不能包含字符“X”,我們可以在類的外面定義一個函數,這個函數需要給定一個形參,用來接收待校驗的數據,並且指定條件下要拋出serializers.ValidationError的異常,如果validators字段值的列表中有多個校驗規則,校驗過程中會全部進行校驗,並以列表的形式返回一組異常校驗信息
from rest_framework import serializers from rest_framework import validators from .models import Projects def name_is_not_contain_x(value): if 'X' in value.upper(): raise serializers.ValidationError("項目名字段name不能包含x的大小寫字符") class ProjectSerializer(serializers.Serializer): name = serializers.CharField(max_length=200, label="項目名稱", help_text='項目名稱', validators=[validators.UniqueValidator(queryset=Projects.objects.all(), message="項目名字段name必須唯一"), name_is_not_contain_x],) leader = serializers.CharField(max_length=50, label="項目負責人", help_text='項目負責人') programmer = serializers.CharField(max_length=50, label="開發人員", help_text="開發人員") tester = serializers.CharField(max_length=50, label="測試人員", help_text="測試人員")
驗證結果:
三、自定義校驗器方法
上面第二種采用的是在序列化器類外面創建的校驗器函數,同樣的也可以在類里面創建一個校驗器方法,不同的有以下幾點:
- 方法名必須以validate_作為前綴,后綴為對應的字段名
- 一定要返回校驗之后的值
- 不需要放在validators的列表中就可以生效
def validate_name(self, value): if '項目' in value: raise serializers.ValidationError("項目名稱name字段不能包含‘項目’字符") return value
驗證結果:
三、自定義多字段校驗器方法
- 上面我們都是單字段進行校驗,如果是多字段同時進行校驗,就需要用到該方法
- 方法名固定為validate,形參固定為attrs
- attrs返回一個QueryDict,字段名可以通過字典的方法進行取值,如:attrs['name'] 或者 attrs.get('name')
- 必須返回attrs
不需要放在validators的列表中就可以生效
def validate(self, attrs): if 'A' in attrs.get('name') and 'B' in attrs.get('leader'): raise serializers.ValidationError("項目名稱字段name不包含A的同時項目負責人字段leader也不能包含B") return attrs
驗證結果:
我們可以看到該異常校驗信息字段的key並不是我們想要的,接下來我們針對這個key進行修改
我們從DRF的源碼settings.py模塊中可以找到這個字段配置信息
修改方法:在django項目下的settings.py模塊中,修改REST_FRAMEWORK字典中的'NON_FIELD_ERRORS_KEY'的值即可
REST_FRAMEWORK = { 'NON_FIELD_ERRORS_KEY': 'more_errors' }
驗證結果: