From 484adc28ec5b4136ff2327bc19202af7656c7198 Mon Sep 17 00:00:00 2001 From: Christian Zosel Date: Thu, 1 Dec 2016 10:08:14 +0100 Subject: [PATCH 1/2] Fix resource_name support for ResourceRelatedField --- rest_framework_json_api/relations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_json_api/relations.py b/rest_framework_json_api/relations.py index b4eefc45..697f8298 100644 --- a/rest_framework_json_api/relations.py +++ b/rest_framework_json_api/relations.py @@ -145,7 +145,7 @@ def to_representation(self, value): # check to see if this resource has a different resource_name when # included and use that name resource_type = None - root = getattr(self.parent, 'parent', self.parent) + root = getattr(self.parent, 'parent', self.parent) or self.parent field_name = self.field_name if self.field_name else self.parent.field_name if getattr(root, 'included_serializers', None) is not None: includes = get_included_serializers(root) From 26186c2feb7aaef19cbf6b5f26798746f366b052 Mon Sep 17 00:00:00 2001 From: Christian Zosel Date: Thu, 1 Dec 2016 17:38:40 +0100 Subject: [PATCH 2/2] Check resource name on included serializer in to_internal_value --- rest_framework_json_api/relations.py | 31 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/rest_framework_json_api/relations.py b/rest_framework_json_api/relations.py index 697f8298..4cb64fd8 100644 --- a/rest_framework_json_api/relations.py +++ b/rest_framework_json_api/relations.py @@ -1,4 +1,5 @@ import collections +import inflection import json from rest_framework.fields import MISSING_ERROR_MESSAGE, SerializerMethodField @@ -123,7 +124,13 @@ def to_internal_value(self, data): self.fail('incorrect_type', data_type=type(data).__name__) if not isinstance(data, dict): self.fail('incorrect_type', data_type=type(data).__name__) + expected_relation_type = get_resource_type_from_queryset(self.queryset) + field_name = inflection.singularize(expected_relation_type) + serializer_resource_type = self.get_resource_type_from_serializer(field_name) + + if serializer_resource_type is not None: + expected_relation_type = serializer_resource_type if 'type' not in data: self.fail('missing_type') @@ -142,18 +149,28 @@ def to_representation(self, value): else: pk = value.pk - # check to see if this resource has a different resource_name when - # included and use that name - resource_type = None - root = getattr(self.parent, 'parent', self.parent) or self.parent field_name = self.field_name if self.field_name else self.parent.field_name + + resource_type = self.get_resource_type_from_serializer(field_name) + if resource_type is None: + resource_type = get_resource_type_from_instance(value) + + return OrderedDict([('type', resource_type), ('id', str(pk))]) + + def get_resource_type_from_serializer(self, field_name): + """ + Given a field_name, check if the serializer has a + corresponding included_serializer with a Meta.resource_name property + + Returns the resource name or None + """ + root = getattr(self.parent, 'parent', self.parent) or self.parent if getattr(root, 'included_serializers', None) is not None: includes = get_included_serializers(root) if field_name in includes.keys(): - resource_type = get_resource_type_from_serializer(includes[field_name]) + return get_resource_type_from_serializer(includes[field_name]) - resource_type = resource_type if resource_type else get_resource_type_from_instance(value) - return OrderedDict([('type', resource_type), ('id', str(pk))]) + return None def get_choices(self, cutoff=None): queryset = self.get_queryset()