Skip to content

Reverse the included relation name formatting #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
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
2 changes: 2 additions & 0 deletions example/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ def __init__(self, *args, **kwargs):
included_serializers = {
'comments': 'example.serializers.CommentSerializer',
'suggested': 'example.serializers.EntrySerializer',
'blog': 'example.serializers.BlogSerializer'
}

blog = serializers.ResourceRelatedField(read_only=True)
body_format = serializers.SerializerMethodField()
comments = relations.ResourceRelatedField(
source='comment_set', many=True, read_only=True)
Expand Down
18 changes: 18 additions & 0 deletions example/tests/integration/test_includes.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,21 @@ def test_missing_field_not_included(author_bio_factory, author_factory, client):
assert 'included' in data
assert len(data['included']) == 1
assert data['included'][0]['attributes']['body'] == bio.body

def test_reverse_included(single_entry, client):
"""Test the parsing of included names"""
from django.conf import settings

parse_relation = getattr(settings, 'JSON_API_PARSE_INCLUDE_KEYS', None)
singularize_included = getattr(settings, 'JSON_API_SINGULARIZE_INCLUDE_TYPE', None)

settings.JSON_API_PARSE_INCLUDE_KEYS = 'underscore'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pytest-django provides a good way of doing this: http://pytest-django.readthedocs.org/en/latest/helpers.html#settings

settings.JSON_API_SINGULARIZE_INCLUDE_TYPE = True

response = client.get(reverse('entry-list') + '?include=blogs')
included = load_json(response.content).get('included')

assert [x.get('type') for x in included] == ['blogs'], 'Related Blogs are incorrect'

settings.JSON_API_PARSE_INCLUDE_KEYS = parse_relation
settings.JSON_API_SINGULARIZE_INCLUDE_TYPE = singularize_included
4 changes: 3 additions & 1 deletion rest_framework_json_api/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,12 @@ def render(self, data, accepted_media_type=None, renderer_context=None):

include_resources_param = request.query_params.get('include') if request else None
if include_resources_param:
included_resources = include_resources_param.split(',')
included_resources = [".".join([utils.parse_relation_name(part) for part in resource.split('.')])
for resource in include_resources_param.split(',')]
else:
included_resources = list()


json_api_included = list()
# initialize json_api_meta with pagination meta or an empty dict
json_api_meta = data.get('meta', {}) if isinstance(data, dict) else {}
Expand Down
4 changes: 2 additions & 2 deletions rest_framework_json_api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from rest_framework_json_api.relations import ResourceRelatedField
from rest_framework_json_api.utils import (
get_resource_type_from_model, get_resource_type_from_instance,
get_resource_type_from_serializer, get_included_serializers)
get_resource_type_from_serializer, get_included_serializers, parse_relation_name)


class ResourceIdentifierObjectSerializer(BaseSerializer):
Expand Down Expand Up @@ -75,7 +75,7 @@ def validate_path(serializer_class, field_path, path):
serializers = get_included_serializers(serializer_class)
if serializers is None:
raise ParseError('This endpoint does not support the include parameter')
this_field_name = field_path[0]
this_field_name = parse_relation_name(field_path[0])
this_included_serializer = serializers.get(this_field_name)
if this_included_serializer is None:
raise ParseError(
Expand Down
11 changes: 11 additions & 0 deletions rest_framework_json_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@ def format_relation_name(value, format_type=None):

return inflection.pluralize(value) if pluralize else value

def parse_relation_name(value, format_type=None):
if format_type is None:
format_type = getattr(settings, 'JSON_API_PARSE_INCLUDE_KEYS', False)

singularize = getattr(settings, 'JSON_API_SINGULARIZE_INCLUDE_TYPE', False)

if format_type:
value = format_value(value, format_type)

return inflection.singularize(value) if singularize else value


def get_related_resource_type(relation):
if hasattr(relation, '_meta'):
Expand Down