31.自定义验证器

反序列化过程中
  • 如果使用is_valid 验证字段通过,我们会获得一个validated_data数据字典
  • 如果验证不通过,会获得一个errors数据字典,is_valid参数如果raise_exception设为True,会弹出ValidationError错误
  • 除了DRF本身的验证,有时候我可以会做一些自定义的验证
 
自定义字段级别验证器
  • 如果我们要在序列化类中添加自定义的字段验证
  • 定义的函数名字必须是 validate_ 开头,下划线后面跟要验证的字段名称
  • 定义的函数参数:value,value是表示原初始的值
from rest_framework.serializers import ModelSerializer
from rest_framework import serializers


class UserSerializer(ModelSerializer):
    class Meta:
        model = UserModel
        fields = ('id', 'title', 'name')

    # 我们要对name字段进行自定义验证,函数名以validate_开头,跟name字段
    def validate_name(self, value):
        # value代表原始的值
        # 判断字段Y 如果不在name中
        if 'Y' not in value.lower():
            # 抛出Serializer的ValidationError异常
            raise serializers.ValidationError('名字必须包含字母Y')

        # 如果验证通过,不对数据进行处理,直接返回数据
        return value
 
 
自定义对象级别验证器
对象级别的验证器
  • 一个序列化类中只能有一个,且函数名字必须是validate
  • 参数:data, 表示完整的传入进来的序列化类中的所有数据dict
  • 涉及到两个及以上字段验证的可以用对象级别验证器
from rest_framework import serializers


class UserSerializer(serializers.Serializer):
    desc = serializers.CharField(max_length=300)
    start_time = serializers.DateTimeField
    end_time = serializers.DateTimeField

    def validate(self, data):
        
        # 检查 starttime是否在endtime之前
        if data['start_time'] > data['end_time']:
            return serializers.ValidationError('time error')
        return data
 
自定义字段参数验证器
  • 字段参数验证器的名字没有要求,参数是value
  • 定义好规则之后,需要使用该验证器的序列化字段里 使用validators=[]来指定验证器
  • 一个字段可以同时使用多个验证器
from rest_framework import serializers
#验证器函数写在序列化内外都可以

class UserSerializer(serializers.Serializer):

    # 定义验证器 参数的值 需要<=1000
    def number(self, value):
        if value > 1000:
            raise serializers.ValidationError('number error')
        

    # 定义验证器 参数的值 需要>30
    def flower(self, value):
        if value < 30:
            raise serializers.ValidationError('flower error')
      

    desc = serializers.CharField(max_length=300)
    start_time = serializers.DateTimeField()
    end_time = serializers.DateTimeField()
    score = serializers.IntegerField(validators=[number]) # 指定number验证器
    flower = serializers.IntegerField(validators=[number,flower]) #指定number、flower两个验证器
to_internal_value和to_representation
  1. DRF所有序列化器类都继承了BaseSerializer 类
  2. 通过重写该类的 to_representation() 和to_internal_value()方法可以改变序列化和反序列化的行为
  3. 比如给序列化后的数据进行处理修改等,或者对请求携带的数据进行反序列化处理以及用来自定义序列化器字段
  4. 序列化过程:queryset -> serializer类 -> to_representation
  5. 反序列化过程:前端提交数据 -> request -> to_internal_value ->field
  6. to_representation() , 转json(序列化)的最后一个步骤,允许我们改变序列化的输出
  7. to_internal_value() ,反序列化的第一个步骤,允许改变我们反序列化的输出
#示例

def to_internal_value(self, data):
    # 反序列化时,将configs类型修改为字符串类型
    data['configs'] = str(data['configs'])
    # 调用父类to_internal_value方法传入修改后的data
    info = super().to_internal_value(data)
    return info #返回修改后的数据

def to_representation(self, instance):
    data = super().to_representation(instance)
    # 序列化时,将字符串类型的configs 转换为字典类型的configs
    data['configs'] = eval(data['configs'])
    return data

'''
to_internal_value用于重新构造validated_data并返回
to_representation用于重新构造serializer.data的值并返回
'''
 

作者:木子七

出处:https://www.cnblogs.com/Mickey-7/p/16715472.html

posted @   木子七  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
workspaces
keyboard_arrow_up dark_mode palette
选择主题