Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions example/tests/test_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from rest_framework_json_api.exceptions import Conflict
from rest_framework_json_api.utils import format_relation_name
from example.models import Blog, Entry, Comment, Author
from example.serializers import CommentSerializer
from rest_framework_json_api.relations import ResourceRelatedField


Expand Down Expand Up @@ -115,6 +116,15 @@ def test_read_only(self):
serializer.is_valid(raise_exception=True)
self.assertNotIn('comment_set', serializer.validated_data)

def test_invalid_resource_id_object(self):
comment = {'body': 'testing 123', 'entry': {'type': 'entry'}, 'author': {'id': '5'}}
serializer = CommentSerializer(data=comment)
assert not serializer.is_valid()
assert serializer.errors == {
'author': ["Invalid resource identifier object: missing 'type' attribute"],
'entry': ["Invalid resource identifier object: missing 'id' attribute"]
}


class BlogFKSerializer(serializers.Serializer):
blog = ResourceRelatedField(queryset=Blog.objects)
Expand Down
10 changes: 10 additions & 0 deletions rest_framework_json_api/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ResourceRelatedField(PrimaryKeyRelatedField):
'does_not_exist': _('Invalid pk "{pk_value}" - object does not exist.'),
'incorrect_type': _('Incorrect type. Expected resource identifier object, received {data_type}.'),
'incorrect_relation_type': _('Incorrect relation type. Expected {relation_type}, received {received_type}.'),
'missing_type': _('Invalid resource identifier object: missing \'type\' attribute'),
'missing_id': _('Invalid resource identifier object: missing \'id\' attribute'),
'no_match': _('Invalid hyperlink - No URL match.'),
}

Expand Down Expand Up @@ -117,8 +119,16 @@ def to_internal_value(self, data):
if not isinstance(data, dict):
self.fail('incorrect_type', data_type=type(data).__name__)
expected_relation_type = get_resource_type_from_queryset(self.queryset)

if 'type' not in data:
self.fail('missing_type')

if 'id' not in data:
self.fail('missing_id')

if data['type'] != expected_relation_type:
self.conflict('incorrect_relation_type', relation_type=expected_relation_type, received_type=data['type'])

return super(ResourceRelatedField, self).to_internal_value(data['id'])

def to_representation(self, value):
Expand Down