Skip to content

Commit

Permalink
Allow run_validators() to handle non-dict types. (#6365)
Browse files Browse the repository at this point in the history
Fixes #6053.

Original test case thanks to Vincent Delaitre in #6242.
  • Loading branch information
carltongibson authored and tomchristie committed Jan 8, 2019
1 parent 0cf18c4 commit 587058e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
7 changes: 5 additions & 2 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,11 @@ 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)
if isinstance(value, dict):
to_validate = self._read_only_defaults()
to_validate.update(value)
else:
to_validate = value
super(Serializer, self).run_validators(to_validate)

def to_internal_value(self, data):
Expand Down
27 changes: 27 additions & 0 deletions tests/test_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ def __len__(self):
assert serializer.validated_data == {'char': 'abc', 'integer': 123}
assert serializer.errors == {}

def test_custom_to_internal_value(self):
"""
to_internal_value() is expected to return a dict, but subclasses may
return application specific type.
"""
class Point(object):
def __init__(self, srid, x, y):
self.srid = srid
self.coords = (x, y)

# 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 Point(srid=4326, **kwargs)

serializer = NestedPointSerializer(data={'longitude': 6.958307, 'latitude': 50.941357})
assert serializer.is_valid()
assert isinstance(serializer.validated_data, 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 == {}


class TestValidateMethod:
def test_non_field_error_validate_method(self):
Expand Down

0 comments on commit 587058e

Please sign in to comment.