27. Django_framework_序列化器和自定義校驗

一、序列化器中的類屬性字段

  • 序列化中所定義的類屬性字段,一般情況下與模型類字段相對應
  • 默認情況下,這些類屬性字段既可以進行序列化輸出,也可以進行反序列化輸入
  • 不需要輸入(反序列化)、輸出(序列化)的字段,則不需要定義
  • 只需要反序列化輸入,則定義write_only = True
  • 只需要序列化輸出,則定義read_only = True
  • 響應的參數如果是多個查詢集,需要在JsonResponse()中傳參many=True
  • label:當前字段在前端的api頁面中所顯示的字段名稱
  • allow_null = False:當前字段是否允許傳None,默認是False(必填字段False,反之則True)
  • allow_blank = False:當前字段是否運行爲空,默認是False(必填字段False,反之則True)

二、反序列化_校驗機制

  • 調用序列化器對象的is_valid()方法,校驗前端參數的正確性,不調用則不校驗
  • 校驗成功返回True、校驗失敗返回False
  • is_valid(raise_exception = True):校驗失敗後,則拋出異常
  • 當調用is_valid()之後,才能調用序列化器對象的errors屬性,內容爲校驗的錯誤提示(dict)
  • views.py中,如果傳參進行了輸入反序列化的話,那麼需要調用的是經過校驗後的數據,比如說新增數據,應該是:xxx類.objects.create(**serializer.validated_data)
    try:
        # 不符合規則則拋出錯誤
        serializer.is_valid(raise_exception=True)  
    except Exception as e:
        # 返回序列化器原有的dict類型的錯誤信息
        return JsonResponse(serializer.errors)

三、rest_framework的校驗器(用於validators=校驗器)

rest_framework.framework中有有多個驗證器,這裏用其中一個最常見的UniqueValidator唯一驗證器示例,更多見:https://juejin.im/post/5aa93246518825555c1d5bba

UniqueValidator唯一校驗器
該驗證器可用於在模型字段上強制實施 unique=True 約束。它需要一個必需的參數和一個可選的 messages 參數:
1. queryset 必須 - 這是校驗唯一性的查詢集,一般是模型類.objects.all()
2. message - 校驗失敗時使用的錯誤消息
3. lookup - 用於查找已校驗值的現有實例。默認爲 ‘exact’

例子:修改之前的serializer.py,對name字段使用UniqueValidator唯一校驗器

name = serializers.CharField(label='用戶名', max_length=128, help_text='用戶名',
                                validators = [
                                    UniqueValidator(
                                        queryset=Projects.objects.all(),
                                        message="該項目名稱已存在")
                                 ])

四、自定義校驗器

注意:如果自定義校驗器中定義的字段,是在所調用的序列化類中所調用的模型類是沒有的字段。那麼就是相當於在模型類的基礎上對字段進行了拓展;
views.py的序列化類上面,添加一個自定義校驗器函數。

def is_unique_user_name(name):
    if '用戶' not in name:
        raise serializers,ValidationError('項目名稱必須含有“項目”')
    else:
        return name

然後在下面的序列化類中這樣調用(看註釋):

 name = serializers.CharField(label='用戶名', max_length=128, help_text='用戶名',
                                validators = [
                                    UniqueValidator(
                                        queryset=Projects.objects.all(),
                                        message="該項目名稱已存在")
                                    ,is_unique_user_name # 在這裏調用自定義校驗器
                                 ]
                                 )  

運行結果:
在這裏插入圖片描述

五 自定義校驗字段級別單個字段的校驗

如果想要對某個特定的字段機械能自定義的驗證規則,那麼可以在所寫的Serializer子類中,添加validate_<filed_name>的方法來指定自定義該字段的驗證

validate_<filed_name>方法需要返回一個驗證過的數據,或者拋出一個serializers.ValidationError異常

例子,修改serializer.py文件

# 自定義字段級別的驗證
    def validate_name(self, value):
        """
        項目需要以“項目”開頭
        :return:
        """
        if not str(value).startswith('項目'):
            # 拋出erializers.ValidationError異常
            raise serializers.ValidationError(detail='項目需要以“項目“兩個字開頭')
        # 返回一個驗證過的數據
        else:
            return value

別的內容無需修改也可以生效:

在這裏插入圖片描述

六.自定義驗證字段級別多個字段的驗證

單個字段的校驗,走的是validate_<filed_name>方法
多個字段的組合校驗,走的是validate方法

  • validate_<filed_name>方法一樣,validate方法也是在在所寫的Serializer子類中,添加validate方法,進行自定義多個字段的驗證
  • serializer.py文件中的Serializer子類添加這個方法,其他不變
    def validate(self, attrs):
        if "靜靜" not in attrs["tester"] and "靜靜" not in attrs["leader"]:
            raise serializers.ValidationError(detail="靜靜必須是測試人員或者經理")
        return attrs

在這裏插入圖片描述

校驗順序:

上面我們看了各種校驗,那麼順序是什麼呢?

  1. 字段定義時候的限制,如參數類型,字段長度,是否可以爲空等;
  2. 自定義的包含validators的列表從左到右邊進行校驗;
  3. validate_字段名單字段校驗;
  4. validate多字段校驗
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章