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
- DRF所有序列化器类都继承了BaseSerializer 类
- 通过重写该类的 to_representation() 和to_internal_value()方法可以改变序列化和反序列化的行为
- 比如给序列化后的数据进行处理修改等,或者对请求携带的数据进行反序列化处理以及用来自定义序列化器字段
- 序列化过程:queryset -> serializer类 -> to_representation
- 反序列化过程:前端提交数据 -> request -> to_internal_value ->field
- to_representation() , 转json(序列化)的最后一个步骤,允许我们改变序列化的输出
- 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的值并返回
'''
风月都好看,人间也浪漫.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!