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

Commit 1c8d835

Browse files
committed
Check resource name on included serializer in to_internal_value
1 parent c869f34 commit 1c8d835

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

rest_framework_json_api/relations.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import collections
2+
import inflection
23
import json
34

45
from rest_framework.fields import MISSING_ERROR_MESSAGE, SerializerMethodField
@@ -123,7 +124,13 @@ def to_internal_value(self, data):
123124
self.fail('incorrect_type', data_type=type(data).__name__)
124125
if not isinstance(data, dict):
125126
self.fail('incorrect_type', data_type=type(data).__name__)
127+
126128
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)
131+
132+
if serializer_resource_type is not None:
133+
expected_relation_type = serializer_resource_type
127134

128135
if 'type' not in data:
129136
self.fail('missing_type')
@@ -142,18 +149,28 @@ def to_representation(self, value):
142149
else:
143150
pk = value.pk
144151

145-
# check to see if this resource has a different resource_name when
146-
# included and use that name
147-
resource_type = None
148-
root = getattr(self.parent, 'parent', self.parent)
149152
field_name = self.field_name if self.field_name else self.parent.field_name
153+
154+
resource_type = self.get_resource_type_from_serializer(field_name)
155+
if resource_type is None:
156+
resource_type = get_resource_type_from_instance(value)
157+
158+
return OrderedDict([('type', resource_type), ('id', str(pk))])
159+
160+
def get_resource_type_from_serializer(self, field_name):
161+
"""
162+
Given a field_name, check if the serializer has a
163+
corresponding included_serializer with a Meta.resource_name property
164+
165+
Returns the resource name or None
166+
"""
167+
root = getattr(self.parent, 'parent', self.parent) or self.parent
150168
if getattr(root, 'included_serializers', None) is not None:
151169
includes = get_included_serializers(root)
152170
if field_name in includes.keys():
153-
resource_type = get_resource_type_from_serializer(includes[field_name])
171+
return get_resource_type_from_serializer(includes[field_name])
154172

155-
resource_type = resource_type if resource_type else get_resource_type_from_instance(value)
156-
return OrderedDict([('type', resource_type), ('id', str(pk))])
173+
return None
157174

158175
def get_choices(self, cutoff=None):
159176
queryset = self.get_queryset()
@@ -219,4 +236,4 @@ def to_representation(self, value):
219236
if isinstance(value, collections.Iterable):
220237
base = super(SerializerMethodResourceRelatedField, self)
221238
return [base.to_representation(x) for x in value]
222-
return super(SerializerMethodResourceRelatedField, self).to_representation(value)
239+
return super(SerializerMethodResourceRelatedField, self).to_representation(value)

0 commit comments

Comments
 (0)