Try second idea: call to_internal_value after validation

This commit is contained in:
Vincent Delaitre 2018-10-15 15:12:55 +02:00
parent 987a7c1ada
commit 73553c99e0

View File

@ -370,12 +370,6 @@ class Serializer(BaseSerializer):
field for field in self.fields.values() if not field.read_only field for field in self.fields.values() if not field.read_only
] ]
@cached_property
def _read_only_fields(self):
return [
field for field in self.fields.values() if field.read_only
]
@cached_property @cached_property
def _readable_fields(self): def _readable_fields(self):
return [ return [
@ -437,10 +431,11 @@ class Serializer(BaseSerializer):
if is_empty_value: if is_empty_value:
return data return data
value = self.to_internal_value(data) value = self._to_primitive_value(data)
try: try:
self.run_validators(value) self.run_validators(value)
value = self.validate(value) value = self.validate(value)
value = self.to_internal_value(value)
assert value is not None, '.validate() should return the validated data' assert value is not None, '.validate() should return the validated data'
except (ValidationError, DjangoValidationError) as exc: except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc)) raise ValidationError(detail=as_serializer_error(exc))
@ -463,7 +458,15 @@ class Serializer(BaseSerializer):
return defaults return defaults
def to_internal_value(self, data): def run_validators(self, value):
"""
Add read_only fields with defaults to value before running validators.
"""
to_validate = self._read_only_defaults()
to_validate.update(value)
super(Serializer, self).run_validators(to_validate)
def _to_primitive_value(self, data):
""" """
Dict of native values <- Dict of primitive datatypes. Dict of native values <- Dict of primitive datatypes.
""" """
@ -477,11 +480,9 @@ class Serializer(BaseSerializer):
ret = OrderedDict() ret = OrderedDict()
errors = OrderedDict() errors = OrderedDict()
writable_fields = self._writable_fields fields = self._writable_fields
read_only_fields = self._read_only_fields
read_only_defaults = self._read_only_defaults()
for field in writable_fields: for field in fields:
validate_method = getattr(self, 'validate_' + field.field_name, None) validate_method = getattr(self, 'validate_' + field.field_name, None)
primitive_value = field.get_value(data) primitive_value = field.get_value(data)
try: try:
@ -497,16 +498,17 @@ class Serializer(BaseSerializer):
else: else:
set_value(ret, field.source_attrs, validated_value) set_value(ret, field.source_attrs, validated_value)
for field in read_only_fields:
primitive_value = field.get_value(read_only_defaults)
if primitive_value is not empty:
set_value(ret, field.source_attrs, primitive_value)
if errors: if errors:
raise ValidationError(errors) raise ValidationError(errors)
return ret return ret
def to_internal_value(self, data):
"""
Converts a dict of primitive datatypes into the internal format
"""
return data
def to_representation(self, instance): def to_representation(self, instance):
""" """
Object instance -> Dict of primitive datatypes. Object instance -> Dict of primitive datatypes.