diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index a4b51ae9d..2ee566006 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -563,10 +563,10 @@ class ListSerializer(BaseSerializer): assert self.child is not None, '`child` is a required argument.' assert not inspect.isclass(self.child), '`child` has not been instantiated.' super(ListSerializer, self).__init__(*args, **kwargs) - self.child.bind(field_name='', parent=self) def bind(self, field_name, parent): super(ListSerializer, self).bind(field_name, parent) + self.child.bind(field_name='', parent=self) self.partial = self.parent.partial def get_initial(self): diff --git a/tests/test_root.py b/tests/test_root.py new file mode 100644 index 000000000..079de531c --- /dev/null +++ b/tests/test_root.py @@ -0,0 +1,62 @@ +from __future__ import unicode_literals + +from django.test import TestCase, override_settings + +from rest_framework import serializers + + +class ChildSerializer(serializers.Serializer): + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + # Not calling self.root + + def to_internal_value(self, data): + value = super().to_internal_value(data) + value['root'] = self.root + return value + + +class AnotherChildSerializer(serializers.Serializer): + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + self.root # Calling self.root to ruin the cache + + def to_internal_value(self, data): + value = super().to_internal_value(data) + value['root'] = self.root + return value + + +class ParentSerializer(serializers.Serializer): + children = ChildSerializer(many=True) + other_children = AnotherChildSerializer(many=True) + + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + # Not calling self.root + + def to_internal_value(self, data): + value = super().to_internal_value(data) + value['root'] = self.root + return value + + +class RootSerializer(serializers.Serializer): + parents = ParentSerializer(many=True) + + +class ListManyToManyTests(TestCase): + def setUp(self): + self.root = RootSerializer(data={ + 'parents': [{ + 'children': [{'name': 'child'}], + 'other_children': [{'name': 'child'}], + }], + }) + self.root.is_valid() + + def test_relative_hyperlinks(self): + assert self.root.root == self.root + assert self.root.validated_data['parents'][0]['root'] == self.root + assert self.root.validated_data['parents'][0]['children'][0]['root'] == self.root + assert self.root.validated_data['parents'][0]['other_children'][0]['root'] == self.root