Skip to content

Commit 38c2ab0

Browse files
committed
Respect serializer's id field.
1 parent 435325e commit 38c2ab0

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

example/tests/unit/test_renderer_class_methods.py

+34
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,40 @@ def test_build_json_resource_obj():
4141
serializer.fields, resource, resource_instance, 'user') == output
4242

4343

44+
class PrefixedId(serializers.CharField):
45+
def get_attribute(self, instance):
46+
return 'my-id-' + str(instance.id)
47+
48+
def to_internal_value(self, data):
49+
return int(data['id'].split('-')[-1])
50+
51+
52+
class ResourceWithIdSerializer(serializers.ModelSerializer):
53+
id = PrefixedId(required=False)
54+
55+
class Meta:
56+
fields = ('id', 'username',)
57+
model = get_user_model()
58+
59+
60+
def test_build_json_resource_obj_respects_serializer_id():
61+
serializer = ResourceWithIdSerializer(data={'username': 'Alice'})
62+
serializer.is_valid()
63+
resource_instance = serializer.save()
64+
resource = serializer.data
65+
66+
output = {
67+
'type': 'user',
68+
'id': 'my-id-1',
69+
'attributes': {
70+
'username': 'Alice'
71+
},
72+
}
73+
74+
assert JSONRenderer.build_json_resource_obj(
75+
serializer.fields, resource, resource_instance, 'user') == output
76+
77+
4478
def test_can_override_methods():
4579
"""
4680
Make sure extract_attributes and extract_relationships can be overriden.

rest_framework_json_api/renderers.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,16 @@ def build_json_resource_obj(cls, fields, resource, resource_instance, resource_n
498498
# Determine type from the instance if the underlying model is polymorphic
499499
if force_type_resolution:
500500
resource_name = utils.get_resource_type_from_instance(resource_instance)
501+
502+
# Allow serializer `id` field to override model pk
503+
if 'id' in resource:
504+
resource_id = encoding.force_text(resource['id'])
505+
else:
506+
resource_id = encoding.force_text(resource_instance.pk) if resource_instance else None
507+
501508
resource_data = [
502509
('type', resource_name),
503-
('id', encoding.force_text(resource_instance.pk) if resource_instance else None),
510+
('id', resource_id),
504511
('attributes', cls.extract_attributes(fields, resource)),
505512
]
506513
relationships = cls.extract_relationships(fields, resource, resource_instance)

0 commit comments

Comments
 (0)