mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-02 19:40:13 +03:00
Fixing #6053: injection of read-only default values is done too late
This commit is contained in:
parent
1c3f796219
commit
987a7c1ada
|
@ -370,6 +370,12 @@ 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 [
|
||||||
|
@ -457,14 +463,6 @@ class Serializer(BaseSerializer):
|
||||||
|
|
||||||
return defaults
|
return defaults
|
||||||
|
|
||||||
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_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
"""
|
"""
|
||||||
Dict of native values <- Dict of primitive datatypes.
|
Dict of native values <- Dict of primitive datatypes.
|
||||||
|
@ -479,9 +477,11 @@ class Serializer(BaseSerializer):
|
||||||
|
|
||||||
ret = OrderedDict()
|
ret = OrderedDict()
|
||||||
errors = OrderedDict()
|
errors = OrderedDict()
|
||||||
fields = self._writable_fields
|
writable_fields = self._writable_fields
|
||||||
|
read_only_fields = self._read_only_fields
|
||||||
|
read_only_defaults = self._read_only_defaults()
|
||||||
|
|
||||||
for field in fields:
|
for field in writable_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,6 +497,11 @@ 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)
|
||||||
|
|
||||||
|
|
|
@ -613,3 +613,32 @@ class TestDeclaredFieldInheritance:
|
||||||
assert len(Parent().get_fields()) == 2
|
assert len(Parent().get_fields()) == 2
|
||||||
assert len(Child().get_fields()) == 2
|
assert len(Child().get_fields()) == 2
|
||||||
assert len(Grandchild().get_fields()) == 2
|
assert len(Grandchild().get_fields()) == 2
|
||||||
|
|
||||||
|
|
||||||
|
class Test5922Regression:
|
||||||
|
class Point(object):
|
||||||
|
def __init__(self, srid, x, y):
|
||||||
|
self.srid = srid
|
||||||
|
self.coords = (x, y)
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
|
||||||
|
# Declares a serializer that converts data into an object
|
||||||
|
class NestedPointSerializer(serializers.Serializer):
|
||||||
|
longitude = serializers.FloatField(source='x')
|
||||||
|
latitude = serializers.FloatField(source='y')
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
kwargs = super(NestedPointSerializer, self).to_internal_value(data)
|
||||||
|
return Test5922Regression.Point(srid=4326, **kwargs)
|
||||||
|
|
||||||
|
self.Serializer = NestedPointSerializer
|
||||||
|
|
||||||
|
def test_5922_regression(self):
|
||||||
|
serializer = self.Serializer(data={'longitude': 6.958307, 'latitude': 50.941357})
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert isinstance(serializer.validated_data, Test5922Regression.Point)
|
||||||
|
assert serializer.validated_data.srid == 4326
|
||||||
|
assert serializer.validated_data.coords[0] == 6.958307
|
||||||
|
assert serializer.validated_data.coords[1] == 50.941357
|
||||||
|
assert serializer.errors == {}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user