diff --git a/example/tests/unit/test_renderer_class_methods.py b/example/tests/unit/test_renderer_class_methods.py index 7a9230d3..ebb9b3c2 100644 --- a/example/tests/unit/test_renderer_class_methods.py +++ b/example/tests/unit/test_renderer_class_methods.py @@ -41,6 +41,40 @@ def test_build_json_resource_obj(): serializer.fields, resource, resource_instance, 'user') == output +class PrefixedId(serializers.CharField): + def get_attribute(self, instance): + return 'my-id-' + str(instance.id) + + def to_internal_value(self, data): + return int(data['id'].split('-')[-1]) + + +class ResourceWithIdSerializer(serializers.ModelSerializer): + id = PrefixedId(required=False) + + class Meta: + fields = ('id', 'username',) + model = get_user_model() + + +def test_build_json_resource_obj_respects_serializer_id(): + serializer = ResourceWithIdSerializer(data={'username': 'Alice'}) + serializer.is_valid() + resource_instance = serializer.save() + resource = serializer.data + + output = { + 'type': 'user', + 'id': 'my-id-1', + 'attributes': { + 'username': 'Alice' + }, + } + + assert JSONRenderer.build_json_resource_obj( + serializer.fields, resource, resource_instance, 'user') == output + + def test_can_override_methods(): """ Make sure extract_attributes and extract_relationships can be overriden. diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index ba41a061..47f00a50 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -487,9 +487,16 @@ def build_json_resource_obj(cls, fields, resource, resource_instance, resource_n # Determine type from the instance if the underlying model is polymorphic if force_type_resolution: resource_name = utils.get_resource_type_from_instance(resource_instance) + + # Allow serializer `id` field to override model pk + if 'id' in resource: + resource_id = encoding.force_text(resource['id']) + else: + resource_id = encoding.force_text(resource_instance.pk) if resource_instance else None + resource_data = [ ('type', resource_name), - ('id', encoding.force_text(resource_instance.pk) if resource_instance else None), + ('id', resource_id), ('attributes', cls.extract_attributes(fields, resource)), ] relationships = cls.extract_relationships(fields, resource, resource_instance)