DRF框架serializer反序列化校驗之validators


  反序列化過程中,除了校驗字段類型和長度大小之外,還需要有其它的條件限制的校驗,這時我們可以使用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'
}

驗證結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM