反序列化校验源码分析
2023-12-22 15:56:18
1 ?执行 ser.is_valid() 就会执行 反序列化的校验---》字段自己--》局部钩子---》全局钩子
2 ?入口是:ser.is_valid()---》BaseSerializer
1 自己写的BookSerializer---》serializer.Serializer---->BaseSerializer
2 源码如下
def is_valid(self, *, raise_exception=False):
# self 是 ser对象---》自己写的BookSerializer的对象--》一开始没有
# 一旦有了,就不执行了,优化is_valid被多次调用,只会走一次校验
if not hasattr(self, '_validated_data'):
try:
# 一旦执行过,以后self中就有_validated_data
# 接下来看self.run_validation(self.initial_data)
self._validated_data = self.run_validation(self.initial_data)
except ValidationError as exc:
self._validated_data = {}
self._errors = exc.detail
else:
self._errors = {}
if self._errors and raise_exception:
raise ValidationError(self.errors)
return not bool(self._errors)
?
3 self.run_validation(self.initial_data)---》serializer.Serializer类的,不要按住ctrl点击,否则会进 Field 类
4 serializer.Serializer类的run_validation
def run_validation(self, data=empty):
# data前端传入的--{"name":"张三","age":68}
# value是---》前端传入的,字段自己校验通过的字典---{"name":"张三","age":68}
value = self.to_internal_value(data) # 执行局部钩子
try:
self.run_validators(value) # 先不看,忽略掉
# self 是 BookSerializer的对象,如果我们写了全局钩子,走我们自己的,如果没写,走父类的,父类的根本没做校验
# value={"name":"张三","age":68}
value = self.validate(value)# 执行全局钩子
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
5 全局钩子读完了:self 是 BookSerializer的对象,如果我们写了全局钩子,走我们自己的,如果没写,走父类的,父类的根本没做校验
6 局部钩子:value = self.to_internal_value(data)--》Serializer类的
# for循环着去BookSerializer的对象中反射 validate_字段名的方法,如果有就执行,没有就不执行
def to_internal_value(self, data):
for field in fields: # 序列化类中所有字段类的对象 name=CharField()
# self 是BookSerializer类的对象
# 去BookSerializer类中,反射 validate_field字段类的对象.field_name
validate_method = getattr(self, 'validate_' + field.field_name, None)
try:
# 如果能拿到,说明咱么写了局部钩子
if validate_method is not None:
# 执行局部钩子--》传入了当前字段的value值
validated_value = validate_method(validated_value)
except ValidationError as exc:
# 如果抛异常,会被捕获
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = get_error_detail(exc)
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
文章来源:https://blog.csdn.net/m0_71115526/article/details/135153216
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!