反序列化类校验部分源码解析
# 反序列化校验、什么时候开始执行校验
视图类中的 ser.is_valid(),就会执行校验,校验通过返回True,不通过返回False
# 入口:ser.is_valid() 是序列化类的对象,假设序列化类是BookSerializer--》is_valid()---》找不到, 找到父类BookSerializer中有:【raise_exception:先注意】
def is_valid(self, *, raise_exception=False):
if not hasattr(self, '_validated_data'):
try:
# self序列化类的对象,属性中没有_validated_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)
# self._validated_data = self.run_validation(self.initial_data) 核心---》self序列化类的对象
切记一定不要按住ctrl键点击
真正的执行顺序是,从上往下找,找不到,再往上
最终从Serializer类中找到了run_validation而不是Field中的run_validation
def run_validation(self, data=empty):
# 字段自己的 validates方法
(is_empty_value, data) = self.validate_empty_values(data)
if is_empty_value:
return data
# 局部钩子 ----【局部钩子】
value = self.to_internal_value(data)
try:
self.run_validators(value)
# 全局钩子---》如果在BookSerializer中写了validate,优先走它 非常简单
value = self.validate(value)
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
# 局部钩子 self.to_internal_value(data) ---》self是BookSerializer的对象 从根上找
def to_internal_value(self, data):
ret = OrderedDict()
errors = OrderedDict()
fields = self._writable_fields
# fields写在序列化类中一个个字段类的对象
for field in fields:
# self BookSerializer的对象,反射validate_name
validate_method = getattr(self, 'validate_' + field.field_name, None)
try:
# 在执行BookSerializer类中的validate_name方法,传入了要校验的数据
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
断言assert
# 源码中大量使用try和断言
# 关键字assert,有什么作用,断定是xx 如果不是就抛异常
name = 'lqz'
# if name == 'lqz':
# print('对了')
# else:
# # print('错了')
# raise Exception('名字不为lqz,不能继续走了')
assert name=='lqz' # 断定是,如果不是,就抛异常
print('后续代码')
drf请求
Request能够解析的前端传入的编码格式
# 需求是该接口只能介绍json格式,不能接收其他格式
# 方式一 在继承自APIView及其子类的视图类中配置(局部配置)
# 总共有三个:form rest_framework.parsers import
标签:errors,self,value,视图,序列化,data,drf
From: https://www.cnblogs.com/xm15/p/17090174.html