# 序列化类的校验功能
局部钩子:必须 validate_字段名
全局钩子:validate
# 入口
ser.is_valid 才做的校验---》入口
先从自己写的BookSerializer类中找is_valid方法----》再到继承的父类Serializer中找---》再到它的父类BaseSerializer中找----》is_valid---》还继承了Field
'''BookSerializer类中的is_valid方法'''defis_valid(self, *, raise_exception=False):
# self中没有_validated_data,只有执行完后,才有(校验过后的数据)ifnothasattr(self, '_validated_data'):
try:
# 核心---》这一句# 想看它的源代码,按住ctrl+鼠标点击是不对的---》只能找当前类的父类,要从根上开始找
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)
returnnotbool(self._errors)
"""
self.run_validation(self.initial_data)
在Serializer中有run_validation这个方法先执行这个
"""defrun_validation(self, data=empty):
# 局部钩子
value = self.to_internal_value(data)
try:
# 全局钩子
value = self.validate(value) # BookSerializer只要写了,优先执行它的except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
"""
局部钩子
self.to_internal_value(data)---》Serializer类的方法
"""defto_internal_value(self, data):
for field in fields: #序列化类中写的一个个的字段类的对象列表# 一个field是name对象,field.field_name字符串 name# self是谁的对象:序列化类的对象,BookSerializer的对象 validate_name
validate_method = getattr(self, 'validate_' + field.field_name, None)
try:
# 字段自己的校验规则
validated_value = field.run_validation(primitive_value)
if validate_method isnotNone:
# 局部钩子
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:
passelse:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
# 总结
ser.is_valid--->走局部钩子的代码---》是通过反射获取BookSerializer中写的局部钩子函数,如果写了,就会执行---》走全局钩子代码---》self.validate(value)---》只要序列化类中写了,优先走自己的
3.断言
asserthasattr(self, 'initial_data'), (
'Cannot call `.is_valid()` as no `data=` keyword argument was ''passed when instantiating the serializer instance.'
)
# 断言某个东西是我认为的,如果不是就抛异常# 等同于if判断+抛异常defadd(a,b):
return a + b
res = add(8,9)
# assert res == 16,Exception('不等于16')ifnot res == 16:
raise Exception('不等于16')
print('随便')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix