Skip to content

Commit 587058e

Browse files
carltongibsontomchristie
authored andcommitted
Allow run_validators() to handle non-dict types. (#6365)
Fixes #6053. Original test case thanks to Vincent Delaitre in #6242.
1 parent 0cf18c4 commit 587058e

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

rest_framework/serializers.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,11 @@ def run_validators(self, value):
461461
"""
462462
Add read_only fields with defaults to value before running validators.
463463
"""
464-
to_validate = self._read_only_defaults()
465-
to_validate.update(value)
464+
if isinstance(value, dict):
465+
to_validate = self._read_only_defaults()
466+
to_validate.update(value)
467+
else:
468+
to_validate = value
466469
super(Serializer, self).run_validators(to_validate)
467470

468471
def to_internal_value(self, data):

tests/test_serializer.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,33 @@ def __len__(self):
156156
assert serializer.validated_data == {'char': 'abc', 'integer': 123}
157157
assert serializer.errors == {}
158158

159+
def test_custom_to_internal_value(self):
160+
"""
161+
to_internal_value() is expected to return a dict, but subclasses may
162+
return application specific type.
163+
"""
164+
class Point(object):
165+
def __init__(self, srid, x, y):
166+
self.srid = srid
167+
self.coords = (x, y)
168+
169+
# Declares a serializer that converts data into an object
170+
class NestedPointSerializer(serializers.Serializer):
171+
longitude = serializers.FloatField(source='x')
172+
latitude = serializers.FloatField(source='y')
173+
174+
def to_internal_value(self, data):
175+
kwargs = super(NestedPointSerializer, self).to_internal_value(data)
176+
return Point(srid=4326, **kwargs)
177+
178+
serializer = NestedPointSerializer(data={'longitude': 6.958307, 'latitude': 50.941357})
179+
assert serializer.is_valid()
180+
assert isinstance(serializer.validated_data, Point)
181+
assert serializer.validated_data.srid == 4326
182+
assert serializer.validated_data.coords[0] == 6.958307
183+
assert serializer.validated_data.coords[1] == 50.941357
184+
assert serializer.errors == {}
185+
159186

160187
class TestValidateMethod:
161188
def test_non_field_error_validate_method(self):

0 commit comments

Comments
 (0)