天天看點

Django rest framework動态校驗字段類型

重寫is_valid動态校驗參數

  • 有了 動态傳回字段 怎麼能沒有動态的校驗字段!
  • 看了半天Serializer的實作代碼,終于搗鼓出來了動态校驗字段的方式,該方法還是自己測試階段,沒有開始實際應用,有什麼問題請大家及時回報,我這裡實際使用過以後也會更新本篇的内容。
  • 更新:已經實際應用了,暫時沒有發現問題。

使用方法

  • 調用serializers:傳入的context可以在is_valid中獲得
    context = {
            "data": {
                "name": "rename", 
                "valid": "CharField(required=True)"
            }
        }
    # 調用校驗,傳入的context可以在is_valid中獲得
    DataSerializer(data=validated_data, context=context).is_valid(True)           
  • 資料校驗serializers:重寫is_valid修改

    _declared_fields

    ,然後繼續使用原有的方法校驗
    from rest_framework.serializers import Serializer
    from rest_framework.fields import CharField
    
    
    class DataSerializer(Serializer):
        name = CharField(required=False, allow_null=True, allow_blank=True)
        
        # 重寫is_valid
        def is_valid(self, raise_exception=False):
            data = self.context.get("data")
            if data:
                # 把存儲的字元串轉為可以使用的對象,注意:字元串必須是可以引用的對象,謹慎操作
                valid = eval(data['valid'])
                self._declared_fields[data['name']] = valid
            # 繼續使用原有的方法
            return super().is_valid(raise_exception)           
  • self._declared_fields

    ,需要的校驗規則。
  • self.initial_data

    ,需要校驗的資料,也就是調用時傳入的

    validated_data

  • 使用

    self._declared_fields[data['name']] = valid

    把值加入

    self._declared_fields

    後,Serializers在解析的時候使用

    fields()

    方法,把

    declared_fields

    中的字段進行處理,具體方法不好一一說明,有興趣的可以看一下Serializers的實作代碼,經過以上的重寫

    is_valid()

    後,等價于:
    class DataSerializer(Serializer):
        name = CharField(required=False, allow_null=True, allow_blank=True)
        rename = CharField(required=True)           

幾種允許資料為空的驗證

  • 示例
    from rest_framework.serializers import Serializer
    from rest_framework.fields import CharField
    
    class DataSerializer(Serializer):
        name = CharField(required=False, allow_null=True, allow_blank=True)           
指令 說明
required=False 允許不傳該字段
allow_null=True 允許字段填null name=null
allow_blank=True 允許字段填空字元串 name=""