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)
?
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
# 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