This commit is contained in:
Warren Jin 2015-01-28 10:20:06 -05:00
parent 672df63599
commit a63b9fde2e
2 changed files with 4 additions and 21 deletions

View File

@ -1294,24 +1294,6 @@ class RecursiveField(Field):
next = RecursiveField(allow_null=True) next = RecursiveField(allow_null=True)
""" """
# Implementation notes
#
# Only use __getattribute__ to forward the bound methods. Stop short of
# forwarding all attributes for the following reasons:
# - if you forward the __class__ attribute then deepcopy will give you back
# the wrong class
# - if you forward the fields attribute then __repr__ will enter into an
# infinite recursion
# - who knows what other infinite recursions are possible
#
# We only forward bound methods, but there are some attributes that must be
# accessible on both the RecursiveField and the proxied serializer, namely:
# field_name, read_only, default, source_attrs, write_attrs, source. As far
# as I can tell, the cleanest way to make these fields availabe without
# piecemeal forwarding them through __getattribute__ is to call bind and
# __init__ on both the RecursiveField and the proxied field using the exact
# same arguments.
def __init__(self, to='self', to_module=None, **kwargs): def __init__(self, to='self', to_module=None, **kwargs):
self.to = to self.to = to
self.to_module = to_module self.to_module = to_module
@ -1336,7 +1318,7 @@ class RecursiveField(Field):
ref = importlib.import_module(self.to_module or parent_class.__module__) ref = importlib.import_module(self.to_module or parent_class.__module__)
for part in self.to.split('.'): for part in self.to.split('.'):
ref = getattr(ref, part) ref = getattr(ref, part)
proxy_class = ref proxy_class = ref
proxy = proxy_class(**self._kwargs) proxy = proxy_class(**self._kwargs)
proxy.bind(field_name, parent) proxy.bind(field_name, parent)
@ -1348,7 +1330,7 @@ class RecursiveField(Field):
if 'proxy' in d: if 'proxy' in d:
try: try:
attr = getattr(d['proxy'], name) attr = getattr(d['proxy'], name)
if hasattr(attr, '__self__'): if hasattr(attr, '__self__'):
return attr return attr
except AttributeError: except AttributeError:

View File

@ -1,5 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
class LinkSerializer(serializers.Serializer): class LinkSerializer(serializers.Serializer):
name = serializers.CharField(max_length=25) name = serializers.CharField(max_length=25)
next = serializers.RecursiveField(required=False, allow_null=True) next = serializers.RecursiveField(required=False, allow_null=True)
@ -47,7 +48,7 @@ class TestRecursiveField:
'cannot validate on deserialization: %s' % dict(serializer.errors) 'cannot validate on deserialization: %s' % dict(serializer.errors)
assert serializer.validated_data == data, \ assert serializer.validated_data == data, \
'deserialized data does not match input' 'deserialized data does not match input'
def test_link_serializer(self): def test_link_serializer(self):
value = { value = {
'name': 'first', 'name': 'first',