Skip to content

Add option to specify default included resources #250

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

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
20 changes: 16 additions & 4 deletions example/tests/integration/test_includes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
from django.core.urlresolvers import reverse

from example.tests.utils import load_json
import mock

pytestmark = pytest.mark.django_db


def test_included_data_on_list(multiple_entries, client):
response = client.get(reverse("entry-list") + '?include=comments&page_size=5')

@mock.patch('rest_framework_json_api.utils.get_default_included_resources_from_serializer', new=lambda s: ['comments'])
def test_default_included_data_on_list(multiple_entries, client):
return test_included_data_on_list(multiple_entries=multiple_entries, client=client, query='?page_size=5')


def test_included_data_on_list(multiple_entries, client, query='?include=comments&page_size=5'):
response = client.get(reverse("entry-list") + query)
included = load_json(response.content).get('included')

assert len(load_json(response.content)['data']) == len(multiple_entries), 'Incorrect entry count'
Expand All @@ -18,8 +25,13 @@ def test_included_data_on_list(multiple_entries, client):
assert comment_count == expected_comment_count, 'List comment count is incorrect'


def test_included_data_on_detail(single_entry, client):
response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + '?include=comments')
@mock.patch('rest_framework_json_api.utils.get_default_included_resources_from_serializer', new=lambda s: ['comments'])
def test_default_included_data_on_detail(single_entry, client):
return test_included_data_on_detail(single_entry=single_entry, client=client, query='')


def test_included_data_on_detail(single_entry, client, query='?include=comments'):
response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + query)
included = load_json(response.content).get('included')

assert [x.get('type') for x in included] == ['comments'], 'Detail included types are incorrect'
Expand Down
1 change: 1 addition & 0 deletions requirements-development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pytest-django
pytest-factoryboy
fake-factory
tox
mock
13 changes: 7 additions & 6 deletions rest_framework_json_api/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,6 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
if resource_name == 'errors':
return self.render_errors(data, accepted_media_type, renderer_context)

include_resources_param = request.query_params.get('include') if request else None
if include_resources_param:
included_resources = include_resources_param.split(',')
else:
included_resources = list()

json_api_data = data
json_api_included = list()
# initialize json_api_meta with pagination meta or an empty dict
Expand All @@ -433,6 +427,13 @@ def render(self, data, accepted_media_type=None, renderer_context=None):

serializer = getattr(serializer_data, 'serializer', None)

# Build a list of included resources
include_resources_param = request.query_params.get('include') if request else None
if include_resources_param:
included_resources = include_resources_param.split(',')
else:
included_resources = utils.get_default_included_resources_from_serializer(serializer)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wanted to make sure the include param should override the defaults, which is how you implemented it here.

If an endpoint supports the include parameter and a client supplies it, the server MUST NOT include unrequested resource objects in the included section of the compound document.

👍 , looks like this is all good.


if serializer is not None:

# Get the serializer fields
Expand Down
7 changes: 7 additions & 0 deletions rest_framework_json_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,13 @@ def get_resource_type_from_serializer(serializer):
return get_resource_type_from_model(serializer.Meta.model)


def get_default_included_resources_from_serializer(serializer):
try:
return list(serializer.JSONAPIMeta.included_resources)
except AttributeError:
return []


def get_included_serializers(serializer):
included_serializers = copy.copy(getattr(serializer, 'included_serializers', dict()))

Expand Down