Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 76caa82

Browse files
committed
Improve identification of root serializer
1 parent 1c8d835 commit 76caa82

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

rest_framework_json_api/relations.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ def to_internal_value(self, data):
126126
self.fail('incorrect_type', data_type=type(data).__name__)
127127

128128
expected_relation_type = get_resource_type_from_queryset(self.queryset)
129-
field_name = inflection.singularize(expected_relation_type)
130-
serializer_resource_type = self.get_resource_type_from_serializer(field_name)
129+
serializer_resource_type = self.get_resource_type_from_included_serializer(expected_relation_type)
131130

132131
if serializer_resource_type is not None:
133132
expected_relation_type = serializer_resource_type
@@ -151,27 +150,46 @@ def to_representation(self, value):
151150

152151
field_name = self.field_name if self.field_name else self.parent.field_name
153152

154-
resource_type = self.get_resource_type_from_serializer(field_name)
153+
resource_type = self.get_resource_type_from_included_serializer(field_name)
155154
if resource_type is None:
156155
resource_type = get_resource_type_from_instance(value)
157156

158157
return OrderedDict([('type', resource_type), ('id', str(pk))])
159158

160-
def get_resource_type_from_serializer(self, field_name):
159+
def get_resource_type_from_included_serializer(self, field_name):
161160
"""
162161
Given a field_name, check if the serializer has a
163162
corresponding included_serializer with a Meta.resource_name property
164163
165164
Returns the resource name or None
166165
"""
167166
root = getattr(self.parent, 'parent', self.parent) or self.parent
168-
if getattr(root, 'included_serializers', None) is not None:
167+
root = self.get_root_serializer()
168+
169+
if root is not None:
170+
# accept both singular and plural versions of field_name
171+
field_names = [
172+
inflection.singularize(field_name),
173+
inflection.pluralize(field_name)
174+
]
169175
includes = get_included_serializers(root)
170-
if field_name in includes.keys():
171-
return get_resource_type_from_serializer(includes[field_name])
176+
for field in field_names:
177+
if field in includes.keys():
178+
return get_resource_type_from_serializer(includes[field])
172179

173180
return None
174181

182+
def get_root_serializer(self):
183+
if hasattr(self.parent, 'parent') and self.is_serializer(self.parent.parent):
184+
return self.parent.parent
185+
elif self.is_serializer(self.parent):
186+
return self.parent
187+
188+
return None
189+
190+
def is_serializer(self, candidate):
191+
return hasattr(candidate, 'included_serializers')
192+
175193
def get_choices(self, cutoff=None):
176194
queryset = self.get_queryset()
177195
if queryset is None:

0 commit comments

Comments
 (0)