首页 > 其他分享 >反序列化(钩子函数进行复杂数据验证)

反序列化(钩子函数进行复杂数据验证)

时间:2022-10-24 17:25:25浏览次数:59  
标签:serializers 验证 钩子 age 序列化 data serializer

反序列化(钩子函数进行复杂数据验证)

5.1 验证单个字段

序列化器:

class Student1Serializer1(serializers.Serializer):
    """学生信息序列化器"""

    # 1.转换的字段说明
    # 字段 = serializer.字段类型(选项=选项值)

    id = serializers.IntegerField(read_only=True)  # 反序列化阶段不会要求id有值
    name = serializers.CharField(required=True)  # 反序列化阶段必填
    sex = serializers.CharField(default="男")  # 反序列化阶段如果没填,则使用默认值
    age = serializers.IntegerField(min_value=0, max_value=100, error_messages={
        "min_value": "the age must be age>=100",
        "max_value": "the age must be age<=100"
    })
    classroom = serializers.CharField(default="310",validators=[check_classroom])  # 反序列化阶段如果没填,则使用默认值
    info = serializers.CharField(allow_null=True, allow_blank=True)  # 允许客户端不填写(None),或者为""

    # 2.如果当前序列化器继承的是Modelserializer,则需要声明需要调用的模型信息
    # class Meta:
    #     model = 模型名
    #     fields = ["数据库字段名1","数据库字段名2","数据库字段名3",....,"数据库字段名n",] 或 "__all__"

    # 3.验证代码的对象方法(钩子函数)

    def validate_name(self, data):  # 方法名必须以validate_<字段名>来命名
        """
        验证单个字段
        该方法会自动被is_valid()调用
        """
        if data in ["python","django"]:
            raise serializers.ValidationError("学生姓名不能是python或django")

        # 验证成功必须返回data
        return data

    # 4.模型操作方法

    # def create(self, validated_data): # 添加数据后,字典自动变为模型对象
    #     pass
    #
    # def update(self, instance, validated_data): # 更新数据后,字典自动变为模型对象
    #     pass

视图

class StudentView(View):

    def get(self, request):
        """反序列化-采用字段选项来验证数据-验证失败抛出异常"""
        # 1.接收客户端提交的数据
        # data = json.loads(request.body)
        data = {
            "name": "python",
            "age": 30,
            "sex": "男",
            "classroom": "666",
            "info": "要做个猛男,要猛!"
        }
        # 2.实例化序列化器,获取序列化对象
        serializer = Student1Serializer1(data=data)
        # 3.调用序列化器进行数据验证
        ret = serializer.is_valid() 
        # 4.获取验证以后的结果
        if ret:
            return JsonResponse(dict(serializer.validated_data), safe=False)
        else:
            return JsonResponse(dict(serializer.errors), safe=False)
        # 5.操作数据库

        # 6.返回结果

测试结果

{
    "name": [
        "学生姓名不能是python或django"
    ]
}

5.2 验证多个字段

序列化器:

class Student1Serializer1(serializers.Serializer):
    """学生信息序列化器"""

    # 1.转换的字段说明
    # 字段 = serializer.字段类型(选项=选项值)

    id = serializers.IntegerField(read_only=True)  # 反序列化阶段不会要求id有值
    name = serializers.CharField(required=True)  # 反序列化阶段必填
    sex = serializers.CharField(default="男")  # 反序列化阶段如果没填,则使用默认值
    age = serializers.IntegerField(min_value=0, max_value=100, error_messages={
        "min_value": "the age must be age>=100",
        "max_value": "the age must be age<=100"
    })
    classroom = serializers.CharField(default="310",validators=[check_classroom])  # 反序列化阶段如果没填,则使用默认值
    info = serializers.CharField(allow_null=True, allow_blank=True)  # 允许客户端不填写(None),或者为""

    # 2.如果当前序列化器继承的是Modelserializer,则需要声明需要调用的模型信息
    # class Meta:
    #     model = 模型名
    #     fields = ["数据库字段名1","数据库字段名2","数据库字段名3",....,"数据库字段名n",] 或 "__all__"

    # 3.验证代码的对象方法(钩子函数)
    def validate(self, attrs):  # validate是固定的
        """
        验证来自客户端的所有数据
        :param: attrs 序列化器实例化时,传入的data
        这个方法经常用于密码和确认密码的校验,因为需要多个字段的数据
        """

        # 310教室只有女生,不能有男生
        if attrs["classroom"]=="310" and attrs["sex"] == "男":
            raise serializers.ValidationError("310教室不能有男生,只能有小姐姐。")
        return attrs

    # 4.模型操作方法

    # def create(self, validated_data): # 添加数据后,字典自动变为模型对象
    #     pass
    #
    # def update(self, instance, validated_data): # 更新数据后,字典自动变为模型对象
    #     pass

视图

class StudentView(View):

    def get(self, request):
        """反序列化-采用字段选项来验证数据-验证失败抛出异常"""
        # 1.接收客户端提交的数据
        # data = json.loads(request.body)
        data = {
            "name": "彭于晏",
            "age": 30,
            "sex": "男",
            "classroom": "310",
            "info": "要做个猛男,要猛!"
        }
        # 2.实例化序列化器,获取序列化对象
        serializer = Student1Serializer1(data=data)
        # 3.调用序列化器进行数据验证
        ret = serializer.is_valid() 
        # 4.获取验证以后的结果
        if ret:
            return JsonResponse(dict(serializer.validated_data), safe=False)
        else:
            return JsonResponse(dict(serializer.errors), safe=False)
        # 5.操作数据库

        # 6.返回结果

测试结果

{
    "non_field_errors": [
        "310教室不能有男生,只能有小姐姐。"
    ]
}

5.3 外部函数验证

外部函数

def check_classroom(data):
    """外部验证函数"""
    if data == "444":
        raise serializers.ValidationError("444教室学生已满")

    return data

序列化器:

在要验证的字段的validators里加入外部函数名,注意不要加()调用也不要使用字符串

id = serializers.IntegerField(read_only=True)  # 反序列化阶段不会要求id有值
    name = serializers.CharField(required=True)  # 反序列化阶段必填
    sex = serializers.CharField(default="男")  # 反序列化阶段如果没填,则使用默认值
    age = serializers.IntegerField(min_value=0, max_value=100, error_messages={
        "min_value": "the age must be age>=100",
        "max_value": "the age must be age<=100"
    })
    classroom = serializers.CharField(default="310",validators=[check_classroom])  # 反序列化阶段如果没填,则使用默认值
    info = serializers.CharField(allow_null=True, allow_blank=True)  # 允许客户端不填写(None),或者为""

视图

class StudentView(View):

    def get(self, request):
        """反序列化-采用字段选项来验证数据-验证失败抛出异常"""
        # 1.接收客户端提交的数据
        # data = json.loads(request.body)
        data = {
            "name": "彭于晏",
            "age": 30,
            "sex": "男",
            "classroom": "444",
            "info": "要做个猛男,要猛!"
        }
        # 2.实例化序列化器,获取序列化对象
        serializer = Student1Serializer1(data=data)
        # 3.调用序列化器进行数据验证
        ret = serializer.is_valid() 
        # 4.获取验证以后的结果
        if ret:
            return JsonResponse(dict(serializer.validated_data), safe=False)
        else:
            return JsonResponse(dict(serializer.errors), safe=False)
        # 5.操作数据库

        # 6.返回结果

测试结果

{
    "classroom": [
        "444教室学生已满"
    ]
}

标签:serializers,验证,钩子,age,序列化,data,serializer
From: https://www.cnblogs.com/minqiliang/p/16822123.html

相关文章

  • 反序列化(添加和更新)
    反序列化(添加和更新)6.1添加数据序列化器classStudent1Serializer1(serializers.Serializer):"""学生信息序列化器"""#1.转换的字段说明#字段=s......
  • 模型类序列化器
    模型类序列化器7.1序列化多条数据序列化器classStudentModelSerializer(serializers.ModelSerializer):"""学生信息序列化器"""classMeta:model......
  • 序列化器的简单使用
    序列化器的简单使用3.1新建appdjango-adminstartappsers3.2注册appINSTALLED_APPS=[#'django.contrib.admin','django.contrib.auth','django.......
  • POJ 1825/2279(Young/Mr. Young's Picture Permutations-杨氏矩阵和钩子公式)
    给出一个n行的矩阵,每一行有a[i]个数,总共有sum个数,要求每一个位置的数必须比上面的数和左面的数大,求总方案数.杨氏矩阵又叫杨氏图表,它是这样一个矩阵,满足条件:(1)如果格子......
  • 对二分类模型采用十折交叉验证评估
    14、对二分类模型采用十折交叉验证评估#导入必要的包importtorchimporttorch.nnasnnfromtorch.utils.dataimportTensorDataset,DataLoaderfromtorch.nnimpo......
  • 对回归模型采用十折交叉验证评估
    13、对回归模型采用十折交叉验证评估#导入必要的包importtorchfromtorchimportnnimportnumpyasnpimportmatplotlib.pyplotaspltfromtorch.utils.dataim......
  • Apache Log4j Server 反序列化【CVE-2017-5645】
    ApacheLog4jServer反序列化【CVE-2017-5645】ApacheLog4j是一个用于Java的日志记录库,其支持启动远程日志服务器。ApacheLog4j2.8.2之前的2.x版本中存在安全漏洞。攻......
  • C# 配置EF接口报错:ObjectContent`1”类型未能序列化内容类型“application/json; char
    WebApi项目中,配置了EntityFramework,一顿LINQ操作后接口调试出现以下错误:{"Message":"出现错误。","ExceptionMessage":"“ObjectContent`1”类型未能序列化内容......
  • redis采用fastjson序列化方式
    packagecom.wangbiao.security.config;importcom.alibaba.fastjson.support.spring.FastJsonRedisSerializer;importorg.springframework.context.annotation.Bean;......
  • Fastjson反序列化(一)
    前置知识Fastjson是一个Java库,可以将Java对象转换为JSON格式,当然它也可以将JSON字符串转换为Java对象。Fastjson可以操作任何Java对象,即使是一些预先存在......