From 27147477b6b464f905a0ffde06a0b8895dd3630c Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Fri, 22 Jan 2016 11:57:16 -0500 Subject: [PATCH 01/56] docs: note about importing serializers --- docs/usage.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index 6809a0da..c6d02030 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -34,6 +34,18 @@ record count and a `links` object with the next, previous, first, and last links Pages can be selected with the `page` GET parameter. Page size can be controlled per request via the `PAGINATE_BY_PARAM` query parameter (`page_size` by default). +### Serializers + +It is recommended to import the base serializer classes from this package +rather than from vanilla DRF. For example, + +```python +from rest_framework_json_api import serializers + +class MyModelSerializer(serializers.ModelSerializers): + # ... +``` + ### Setting the resource_name You may manually set the `resource_name` property on views or serializers to From 3f719acf830d9b26427b5220d26372172cc1d9b9 Mon Sep 17 00:00:00 2001 From: Leifur Halldor Asgeirsson Date: Fri, 22 Jan 2016 13:06:52 -0500 Subject: [PATCH 02/56] Document ResourceRelatedField and RelationshipView --- docs/usage.md | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index c6d02030..9f8cb98d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -238,6 +238,160 @@ When set to pluralize: Both `JSON_API_PLURALIZE_RELATION_TYPE` and `JSON_API_FORMAT_RELATION_KEYS` can be combined to achieve different results. +### Related fields + +Because of the additional structure needed to represent relationships in JSON +API, this package provides the `ResourceRelatedField` for serializers, which +works similarly to `PrimaryKeyRelatedField`. By default, +`rest_framework_json_api.serializers.ModelSerializer` will use this for +related fields automatically. It can be instantiated explicitly as in the +following example: + +```python +from rest_framework_json_api import serializers +from rest_framework_json_api.relations import ResourceRelatedField + +from myapp.models import Order, LineItem, Customer + + +class OrderSerializer(serializers.ModelSerializer): + class Meta: + model = Order + + line_items = ResourceRelatedField( + queryset=LineItem.objects, + many=True # necessary for M2M fields & reverse FK fields + ) + + customer = ResourceRelatedField( + queryset=Customer.objects # queryset argument is required + ) # except when read_only=True + +``` + +In the [JSON API spec](http://jsonapi.org/format/#document-resource-objects), +relationship objects contain links to related objects. To make this work +on a serializer we need to tell the `ResourceRelatedField` about the +corresponding view. Use the `HyperlinkedModelSerializer` and instantiate +the `ResourceRelatedField` with the relevant keyword arguments: + +```python +from rest_framework_json_api import serializers +from rest_framework_json_api.relations import ResourceRelatedField + +from myapp.models import Order, LineItem, Customer + + +class OrderSerializer(serializers.ModelSerializer): + class Meta: + model = Order + + line_items = ResourceRelatedField( + queryset=LineItem.objects, + many=True, + related_link_view_name='order-lineitems-list', + related_link_url_kwarg='order_pk', + self_link_view_name='order_relationships' + ) + + customer = ResourceRelatedField( + queryset=Customer.objects, + related_link_view-name='order-customer-detail', + related_link_url_kwarg='order_pk', + self_link_view_name='order-relationships' + ) +``` + +* `related_link_view_name` is the name of the route for the related +view. + +* `related_link_url_kwarg` is the keyword argument that will be passed +to the view that identifies the 'parent' object, so that the results +can be filtered to show only those objects related to the 'parent'. + +* `self_link_view_name` is the name of the route for the `RelationshipView` +(see below). + +In this example, `reverse('order-lineitems-list', kwargs={'order_pk': 3}` +should resolve to something like `/orders/3/lineitems`, and that route +should instantiate a view or viewset for `LineItem` objects that accepts +a keword argument `order_pk`. The +[drf-nested-routers](https://github.com/alanjds/drf-nested-routers) package +is useful for defining such nested routes in your urlconf. + +The corresponding viewset for the `line-items-list` route in the above example +might look like the following. Note that in the typical use case this would be +the same viewset used for the `/lineitems` endpoints; when accessed through +the nested route `/orders//lineitems` the queryset is filtered using +the `order_pk` keyword argument to include only the lineitems related to the +specified order. + +```python +from rest_framework import viewsets + +from myapp.models import LineItem +from myapp.serializers import LineItemSerializer + + +class LineItemViewSet(viewsets.ModelViewSet): + queryset = LineItem.objects + serializer_class = LineItemSerializer + + def get_queryset(self): + queryset = self.queryset + + # if this viewset is accessed via the 'order-lineitems-list' route, + # it wll have been passed the `order_pk` kwarg and the queryset + # needs to be filtered accordingly; if it was accessed via the + # unnested '/lineitems' route, the queryset should include all LineItems + if 'order_pk' in self.kwargs: + order_pk = self.kwargs['order_pk'] + queryset = queryset.filter(order__pk=order_pk]) + + return queryset +``` + +### RelationshipView +`rest_framework_json_api.views.RelationshipView` is used to build +relationship views (see the +[JSON API spec](http://jsonapi.org/format/#fetching-relationships)). +The `self` link on a relationship object should point to the corresponding +relationship view. + +The relationship view is fairly simple because it only serializes +[Resource Identifier Objects](http://jsonapi.org/format/#document-resource-identifier-objects) +rather than full resource objects. In most cases the following is sufficient: + +```python +from rest_framework_json_api.views import RelationshipView + +from myapp.models import Order + + +class OrderRelationshipView(RelationshipView): + queryset = Order.objects + +``` + +The urlconf would need to contain a route like the following: + +```python +url( + regex=r'^orders/(?P[^/.]+/relationships/(?P[^/.]+)$', + view=OrderRelationshipView.as_view(), + name='order-relationships' +) +``` + +The `related_field` kwarg specifies which relationship to use, so +if we are interested in the relationship represented by the related +model field `Order.line_items` on the Order with pk 3, the url would be +`/order/3/relationships/line_items`. On `HyperlinkedModelSerializer`, the +`ResourceRelatedField` will construct the url based on the provided +`self_link_view_name` keyword argument, which should match the `name=` +provided in the urlconf, and will use the name of the field for the +`related_field` kwarg. + ### Meta You may add metadata to the rendered json in two different ways: `meta_fields` and `get_root_meta`. From eaaad66d264d1bf3cf36bb3aa573a0daf4c93d77 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Thu, 11 Feb 2016 14:03:00 -0600 Subject: [PATCH 03/56] Updated pip install instructions for 2.0.0-beta.2 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 905f15df..5a65a9a6 100644 --- a/README.rst +++ b/README.rst @@ -80,7 +80,7 @@ From PyPI :: - $ pip install djangorestframework-jsonapi==2.0.0-beta.1 + $ pip install djangorestframework-jsonapi==2.0.0-beta.2 From Source From 4465ca8fc429144d32bc10fbf4c1e45c6c625374 Mon Sep 17 00:00:00 2001 From: Sjoerd Arendsen Date: Fri, 12 Feb 2016 16:00:51 +0100 Subject: [PATCH 04/56] Add LimitOffsetPagination --- rest_framework_json_api/pagination.py | 50 ++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/rest_framework_json_api/pagination.py b/rest_framework_json_api/pagination.py index e8b52401..4b64b431 100644 --- a/rest_framework_json_api/pagination.py +++ b/rest_framework_json_api/pagination.py @@ -4,7 +4,7 @@ from collections import OrderedDict from rest_framework import serializers from rest_framework.views import Response -from rest_framework.pagination import PageNumberPagination +from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination from rest_framework.templatetags.rest_framework import replace_query_param @@ -47,3 +47,51 @@ def get_paginated_response(self, data): ('prev', self.build_link(previous)) ]) }) + + +class LimitOffsetPagination(LimitOffsetPagination): + """ + A limit/offset based style. For example: + http://api.example.org/accounts/?page[limit]=100 + http://api.example.org/accounts/?page[offset]=400&page[limit]=100 + """ + limit_query_param = 'page[limit]' + offset_query_param = 'page[offset]' + + def get_last_link(self): + if self.count == 0: + return None + + url = self.request.build_absolute_uri() + url = replace_query_param(url, self.limit_query_param, self.limit) + + offset = self.count - self.limit + return replace_query_param(url, self.offset_query_param, offset) + + def get_first_link(self): + if self.count == 0: + return None + + url = self.request.build_absolute_uri() + url = replace_query_param(url, self.limit_query_param, self.limit) + + offset = 0 + return replace_query_param(url, self.offset_query_param, offset) + + def get_paginated_response(self, data): + return Response({ + 'results': data, + 'meta': { + 'pagination': OrderedDict([ + ('count', self.count), + ('limit', self.limit), + ('offset', self.offset), + ]) + }, + 'links': OrderedDict([ + ('first', self.get_first_link()), + ('last', self.get_last_link()), + ('next', self.get_next_link()), + ('prev', self.get_previous_link()) + ]) + }) \ No newline at end of file From c521ec216d24e129d18d7996430e9097cf92f9cb Mon Sep 17 00:00:00 2001 From: Sjoerd Arendsen Date: Fri, 12 Feb 2016 16:58:50 +0100 Subject: [PATCH 05/56] Dont let the offset go into negative space --- rest_framework_json_api/pagination.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rest_framework_json_api/pagination.py b/rest_framework_json_api/pagination.py index 4b64b431..092a4450 100644 --- a/rest_framework_json_api/pagination.py +++ b/rest_framework_json_api/pagination.py @@ -5,7 +5,7 @@ from rest_framework import serializers from rest_framework.views import Response from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination -from rest_framework.templatetags.rest_framework import replace_query_param +from rest_framework.utils.urls import remove_query_param, replace_query_param class PageNumberPagination(PageNumberPagination): @@ -66,6 +66,10 @@ def get_last_link(self): url = replace_query_param(url, self.limit_query_param, self.limit) offset = self.count - self.limit + + if offset <= 0: + return remove_query_param(url, self.offset_query_param) + return replace_query_param(url, self.offset_query_param, offset) def get_first_link(self): @@ -73,10 +77,7 @@ def get_first_link(self): return None url = self.request.build_absolute_uri() - url = replace_query_param(url, self.limit_query_param, self.limit) - - offset = 0 - return replace_query_param(url, self.offset_query_param, offset) + return remove_query_param(url, self.offset_query_param) def get_paginated_response(self, data): return Response({ From 36d0fc3c54dc0c91196c16875c1b1e2d9b0d38ea Mon Sep 17 00:00:00 2001 From: Sjoerd Arendsen Date: Mon, 15 Feb 2016 14:20:23 +0100 Subject: [PATCH 06/56] Add basic unit test for LimitOffsetPagination --- example/tests/unit/test_pagination.py | 79 +++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 example/tests/unit/test_pagination.py diff --git a/example/tests/unit/test_pagination.py b/example/tests/unit/test_pagination.py new file mode 100644 index 00000000..b0a08a94 --- /dev/null +++ b/example/tests/unit/test_pagination.py @@ -0,0 +1,79 @@ +from collections import OrderedDict + +from rest_framework.request import Request +from rest_framework.test import APIRequestFactory +from rest_framework.utils.urls import replace_query_param + +from rest_framework_json_api.pagination import LimitOffsetPagination + + +factory = APIRequestFactory() + + +class TestLimitOffset: + """ + Unit tests for `pagination.LimitOffsetPagination`. + """ + + def setup(self): + class ExamplePagination(LimitOffsetPagination): + default_limit = 10 + max_limit = 15 + + self.pagination = ExamplePagination() + self.queryset = range(1, 101) + self.base_url = 'http://testserver/' + + def paginate_queryset(self, request): + return list(self.pagination.paginate_queryset(self.queryset, request)) + + def get_paginated_content(self, queryset): + response = self.pagination.get_paginated_response(queryset) + return response.data + + def get_test_request(self, arguments): + return Request(factory.get('/', arguments)) + + def test_valid_offset_limit(self): + """ + Basic test, assumes offset and limit are given. + """ + offset = 10 + limit = 5 + count = len(self.queryset) + last_offset = count - limit + next_offset = 15 + prev_offset = 5 + + request = self.get_test_request({ + self.pagination.limit_query_param: limit, + self.pagination.offset_query_param: offset + }) + base_url = replace_query_param(self.base_url, self.pagination.limit_query_param, limit) + last_url = replace_query_param(base_url, self.pagination.offset_query_param, last_offset) + first_url = base_url + next_url = replace_query_param(base_url, self.pagination.offset_query_param, next_offset) + prev_url = replace_query_param(base_url, self.pagination.offset_query_param, prev_offset) + queryset = self.paginate_queryset(request) + content = self.get_paginated_content(queryset) + next_offset = offset + limit + + expected_content = { + 'results': list(range(offset + 1, next_offset + 1)), + 'links': OrderedDict([ + ('first', first_url), + ('last', last_url), + ('next', next_url), + ('prev', prev_url), + ]), + 'meta': { + 'pagination': OrderedDict([ + ('count', count), + ('limit', limit), + ('offset', offset), + ]) + } + } + + assert queryset == list(range(offset + 1, next_offset + 1)) + assert content == expected_content From 5c53b146af34c1ed46d5017228fae5feeba8699c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20S?= Date: Sun, 21 Feb 2016 14:37:57 +0100 Subject: [PATCH 07/56] Support deeply nested includes Allow skipping of intermediate included models --- example/factories/__init__.py | 2 + example/serializers.py | 5 ++ example/tests/integration/test_includes.py | 69 ++++++++++++++++++++-- rest_framework_json_api/renderers.py | 4 +- rest_framework_json_api/serializers.py | 2 +- 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/example/factories/__init__.py b/example/factories/__init__.py index 129ddf98..eac5f756 100644 --- a/example/factories/__init__.py +++ b/example/factories/__init__.py @@ -22,6 +22,8 @@ class Meta: name = factory.LazyAttribute(lambda x: faker.name()) email = factory.LazyAttribute(lambda x: faker.email()) + bio = factory.RelatedFactory(b'example.factories.AuthorBioFactory', 'author') + class AuthorBioFactory(factory.django.DjangoModelFactory): class Meta: diff --git a/example/serializers.py b/example/serializers.py index c16b7cdf..99cee740 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -32,6 +32,7 @@ def __init__(self, *args, **kwargs): super(EntrySerializer, self).__init__(*args, **kwargs) included_serializers = { + 'authors': 'example.serializers.AuthorSerializer', 'comments': 'example.serializers.CommentSerializer', 'suggested': 'example.serializers.EntrySerializer', } @@ -73,6 +74,10 @@ class Meta: class CommentSerializer(serializers.ModelSerializer): + included_serializers = { + 'entry': EntrySerializer, + 'author': AuthorSerializer + } class Meta: model = Comment diff --git a/example/tests/integration/test_includes.py b/example/tests/integration/test_includes.py index 4e8c79ce..8c4cb587 100644 --- a/example/tests/integration/test_includes.py +++ b/example/tests/integration/test_includes.py @@ -28,6 +28,7 @@ def test_included_data_on_detail(single_entry, client): expected_comment_count = single_entry.comment_set.count() assert comment_count == expected_comment_count, 'Detail comment count is incorrect' + def test_dynamic_related_data_is_included(single_entry, entry_factory, client): entry_factory() response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + '?include=suggested') @@ -39,14 +40,74 @@ def test_dynamic_related_data_is_included(single_entry, entry_factory, client): def test_missing_field_not_included(author_bio_factory, author_factory, client): # First author does not have a bio - author = author_factory() + author = author_factory(bio=None) response = client.get(reverse('author-detail', args=[author.pk])+'?include=bio') data = load_json(response.content) assert 'included' not in data # Second author does - bio = author_bio_factory() - response = client.get(reverse('author-detail', args=[bio.author.pk])+'?include=bio') + author = author_factory() + response = client.get(reverse('author-detail', args=[author.pk])+'?include=bio') data = load_json(response.content) assert 'included' in data assert len(data['included']) == 1 - assert data['included'][0]['attributes']['body'] == bio.body + assert data['included'][0]['attributes']['body'] == author.bio.body + + +def test_deep_included_data_on_list(multiple_entries, client): + response = client.get(reverse("entry-list") + '?include=comments,comments.author,' + 'comments.author.bio&page_size=5') + included = load_json(response.content).get('included') + + assert len(load_json(response.content)['data']) == len(multiple_entries), 'Incorrect entry count' + assert [x.get('type') for x in included] == [ + 'authorBios', 'authorBios', 'authors', 'authors', 'comments', 'comments' + ], 'List included types are incorrect' + + comment_count = len([resource for resource in included if resource["type"] == "comments"]) + expected_comment_count = sum([entry.comment_set.count() for entry in multiple_entries]) + assert comment_count == expected_comment_count, 'List comment count is incorrect' + + author_count = len([resource for resource in included if resource["type"] == "authors"]) + expected_author_count = sum( + [entry.comment_set.filter(author__isnull=False).count() for entry in multiple_entries]) + assert author_count == expected_author_count, 'List author count is incorrect' + + author_bio_count = len([resource for resource in included if resource["type"] == "authorBios"]) + expected_author_bio_count = sum([entry.comment_set.filter( + author__bio__isnull=False).count() for entry in multiple_entries]) + assert author_bio_count == expected_author_bio_count, 'List author bio count is incorrect' + + # Also include entry authors + response = client.get(reverse("entry-list") + '?include=authors,comments,comments.author,' + 'comments.author.bio&page_size=5') + included = load_json(response.content).get('included') + + assert len(load_json(response.content)['data']) == len(multiple_entries), 'Incorrect entry count' + assert [x.get('type') for x in included] == [ + 'authorBios', 'authorBios', 'authors', 'authors', 'authors', 'authors', + 'comments', 'comments'], 'List included types are incorrect' + + author_count = len([resource for resource in included if resource["type"] == "authors"]) + expected_author_count = sum( + [entry.authors.count() for entry in multiple_entries] + + [entry.comment_set.filter(author__isnull=False).count() for entry in multiple_entries]) + assert author_count == expected_author_count, 'List author count is incorrect' + + +def test_deep_included_data_on_detail(single_entry, client): + # Same test as in list but also ensures that intermediate resources (here comments' authors) + # are returned along with the leaf nodes + response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + + '?include=comments,comments.author.bio') + included = load_json(response.content).get('included') + + assert [x.get('type') for x in included] == ['authorBios', 'authors', 'comments'], \ + 'Detail included types are incorrect' + + comment_count = len([resource for resource in included if resource["type"] == "comments"]) + expected_comment_count = single_entry.comment_set.count() + assert comment_count == expected_comment_count, 'Detail comment count is incorrect' + + author_bio_count = len([resource for resource in included if resource["type"] == "authorBios"]) + expected_author_bio_count = single_entry.comment_set.filter(author__bio__isnull=False).count() + assert author_bio_count == expected_author_bio_count, 'Detail author bio count is incorrect' diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index a8e852cf..877ccf8e 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -248,7 +248,9 @@ def extract_included(fields, resource, resource_instance, included_resources): included_resources.remove(field_name) except ValueError: # Skip fields not in requested included resources - continue + # If no child field, directly continue with the next field + if field_name not in [node.split('.')[0] for node in included_resources]: + continue try: relation_instance_or_manager = getattr(resource_instance, field_name) diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index f68d984e..045da2de 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -84,7 +84,7 @@ def validate_path(serializer_class, field_path, path): ) ) if len(field_path) > 1: - new_included_field_path = field_path[-1:] + new_included_field_path = field_path[1:] # We go down one level in the path validate_path(this_included_serializer, new_included_field_path, path) From c6a13ad5766248a60183797f728411da4f0f06b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20S?= Date: Mon, 22 Feb 2016 11:46:58 +0100 Subject: [PATCH 08/56] Add current tox.ini directory to PYTHONPATH in order to use imports form there Fix regression on PY3 caused by unicode_literals --- example/factories/__init__.py | 4 +--- tox.ini | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/factories/__init__.py b/example/factories/__init__.py index eac5f756..0119f925 100644 --- a/example/factories/__init__.py +++ b/example/factories/__init__.py @@ -1,5 +1,4 @@ # -*- encoding: utf-8 -*- -from __future__ import unicode_literals import factory from faker import Factory as FakerFactory @@ -22,8 +21,7 @@ class Meta: name = factory.LazyAttribute(lambda x: faker.name()) email = factory.LazyAttribute(lambda x: faker.email()) - bio = factory.RelatedFactory(b'example.factories.AuthorBioFactory', 'author') - + bio = factory.RelatedFactory('example.factories.AuthorBioFactory', 'author') class AuthorBioFactory(factory.django.DjangoModelFactory): class Meta: diff --git a/tox.ini b/tox.ini index fbb33a91..9ee8fafb 100644 --- a/tox.ini +++ b/tox.ini @@ -14,7 +14,9 @@ deps = drf33: djangorestframework>=3.3,<3.4 -r{toxinidir}/requirements-development.txt -setenv= DJANGO_SETTINGS_MODULE=example.settings.test +setenv = + PYTHONPATH = {toxinidir} + DJANGO_SETTINGS_MODULE=example.settings.test commands = py.test --basetemp={envtmpdir} From 04a531aabfa178eab7e8ffaba8b2e5b6df2a69e7 Mon Sep 17 00:00:00 2001 From: snewcomer Date: Sun, 6 Mar 2016 09:40:18 -0800 Subject: [PATCH 09/56] [FEATURE]: support using get_serializer_class on view --- example/views.py | 4 +++- rest_framework_json_api/serializers.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/example/views.py b/example/views.py index 5982e09e..c8dddc50 100644 --- a/example/views.py +++ b/example/views.py @@ -12,9 +12,11 @@ class BlogViewSet(viewsets.ModelViewSet): class EntryViewSet(viewsets.ModelViewSet): queryset = Entry.objects.all() - serializer_class = EntrySerializer resource_name = 'posts' + def get_serializer_class(self): + return EntrySerializer + class AuthorViewSet(viewsets.ModelViewSet): queryset = Author.objects.all() diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index f68d984e..adfc4f0b 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -94,7 +94,7 @@ def validate_path(serializer_class, field_path, path): included_resources = include_resources_param.split(',') for included_field_name in included_resources: included_field_path = included_field_name.split('.') - this_serializer_class = view.serializer_class + this_serializer_class = view.get_serializer_class() # lets validate the current path validate_path(this_serializer_class, included_field_path, included_field_name) From ccef34fe2c49cb82d1bf4f4544c2070fc52698d6 Mon Sep 17 00:00:00 2001 From: Raymond Reggers Date: Wed, 16 Mar 2016 22:11:20 +0100 Subject: [PATCH 10/56] fixed extract_root_meta for lists --- .gitignore | 3 + docs/api.md | 3 +- docs/usage.md | 15 +++- example/serializers.py | 4 +- example/tests/integration/test_meta.py | 34 +++++++- .../tests/unit/test_renderer_class_methods.py | 48 ++++++------ rest_framework_json_api/renderers.py | 77 +++++++++---------- 7 files changed, 114 insertions(+), 70 deletions(-) diff --git a/.gitignore b/.gitignore index e5428776..3177afc7 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ pip-delete-this-directory.txt # Tox .tox/ + +# VirtualEnv +.venv/ diff --git a/docs/api.md b/docs/api.md index 14da1d8f..a7f8926f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -38,7 +38,7 @@ Gathers the data from serializer fields specified in `meta_fields` and adds it t #### extract_root_meta -`extract_root_meta(serializer, resource, meta)` +`extract_root_meta(serializer, resource)` Calls a `get_root_meta` function on a serializer, if it exists. @@ -47,4 +47,3 @@ Calls a `get_root_meta` function on a serializer, if it exists. `build_json_resource_obj(fields, resource, resource_instance, resource_name)` Builds the resource object (type, id, attributes) and extracts relationships. - diff --git a/docs/usage.md b/docs/usage.md index 7f951e1c..40105b26 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -260,10 +260,17 @@ added to the `meta` object within the same `data` as the serializer. To add metadata to the top level `meta` object add: ``` python -def get_root_meta(self, obj): - return { - 'size': len(obj) - } +def get_root_meta(self, resource, many): + if many: + # Dealing with a list request + return { + 'size': len(resource) + } + else: + # Dealing with a detail request + return { + 'foo': 'bar' + } ``` to the serializer. It must return a dict and will be merged with the existing top level `meta`. diff --git a/example/serializers.py b/example/serializers.py index 99cee740..61812337 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -7,10 +7,10 @@ class BlogSerializer(serializers.ModelSerializer): copyright = serializers.SerializerMethodField() - def get_copyright(self, obj): + def get_copyright(self, resource): return datetime.now().year - def get_root_meta(self, obj): + def get_root_meta(self, resource, many): return { 'api_docs': '/docs/api/blogs' } diff --git a/example/tests/integration/test_meta.py b/example/tests/integration/test_meta.py index af69a910..d854a34b 100644 --- a/example/tests/integration/test_meta.py +++ b/example/tests/integration/test_meta.py @@ -7,7 +7,39 @@ pytestmark = pytest.mark.django_db -def test_top_level_meta(blog, client): +def test_top_level_meta_for_list_view(blog, client): + + expected = { + "data": [{ + "type": "blogs", + "id": "1", + "attributes": { + "name": blog.name + }, + "meta": { + "copyright": datetime.now().year + }, + }], + 'links': { + 'first': 'http://testserver/blogs?page=1', + 'last': 'http://testserver/blogs?page=1', + 'next': None, + 'prev': None + }, + 'meta': { + 'pagination': {'count': 1, 'page': 1, 'pages': 1}, + 'apiDocs': '/docs/api/blogs' + } + } + + response = client.get(reverse("blog-list")) + content_dump = redump_json(response.content) + expected_dump = dump_json(expected) + + assert content_dump == expected_dump + + +def test_top_level_meta_for_detail_view(blog, client): expected = { "data": { diff --git a/example/tests/unit/test_renderer_class_methods.py b/example/tests/unit/test_renderer_class_methods.py index 9671b3d4..61208a32 100644 --- a/example/tests/unit/test_renderer_class_methods.py +++ b/example/tests/unit/test_renderer_class_methods.py @@ -61,38 +61,42 @@ def test_extract_meta(): } assert JSONRenderer.extract_meta(serializer, serializer.data) == expected -def test_extract_root_meta(): - def get_root_meta(obj): - return { - 'foo': 'meta-value' - } - serializer = ResourceSerializer() - serializer.get_root_meta = get_root_meta +class ExtractRootMetaResourceSerializer(ResourceSerializer): + def get_root_meta(self, resource, many): + if many: + return { + 'foo': 'meta-many-value' + } + else: + return { + 'foo': 'meta-value' + } + + +class InvalidExtractRootMetaResourceSerializer(ResourceSerializer): + def get_root_meta(self, resource, many): + return 'not a dict' + + +def test_extract_root_meta(): + serializer = ExtractRootMetaResourceSerializer() expected = { 'foo': 'meta-value', } - assert JSONRenderer.extract_root_meta(serializer, {}, {}) == expected + assert JSONRenderer.extract_root_meta(serializer, {}) == expected def test_extract_root_meta_many(): - def get_root_meta(obj): - return { - 'foo': 'meta-value' - } - - serializer = ResourceSerializer(many=True) - serializer.get_root_meta = get_root_meta + serializer = ExtractRootMetaResourceSerializer(many=True) expected = { - 'foo': 'meta-value' + 'foo': 'meta-many-value' } - assert JSONRenderer.extract_root_meta(serializer, {}, {}) == expected + assert JSONRenderer.extract_root_meta(serializer, {}) == expected def test_extract_root_meta_invalid_meta(): - def get_root_meta(obj): + def get_root_meta(resource, many): return 'not a dict' - serializer = ResourceSerializer() - serializer.get_root_meta = get_root_meta + serializer = InvalidExtractRootMetaResourceSerializer() with pytest.raises(AssertionError) as e_info: - JSONRenderer.extract_root_meta(serializer, {}, {}) - + JSONRenderer.extract_root_meta(serializer, {}) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 877ccf8e..ac0517b9 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -338,13 +338,18 @@ def extract_meta(serializer, resource): return data @staticmethod - def extract_root_meta(serializer, resource, meta): + def extract_root_meta(serializer, resource): + many = False + if hasattr(serializer, 'child'): + many = True + serializer = serializer.child + + data = {} if getattr(serializer, 'get_root_meta', None): - root_meta = serializer.get_root_meta(resource) - if root_meta: - assert isinstance(root_meta, dict), 'get_root_meta must return a dict' - meta.update(root_meta) - return meta + json_api_meta = serializer.get_root_meta(resource, many) + assert isinstance(json_api_meta, dict), 'get_root_meta must return a dict' + data.update(json_api_meta) + return data @staticmethod def build_json_resource_obj(fields, resource, resource_instance, resource_name): @@ -412,6 +417,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None): else: included_resources = list() + json_api_data = data 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 {} @@ -421,51 +427,44 @@ def render(self, data, accepted_media_type=None, renderer_context=None): else: serializer_data = data - if hasattr(serializer_data, 'serializer') and getattr(serializer_data.serializer, 'many', False): - # The below is not true for non-paginated responses - # and isinstance(data, dict): - - # If detail view then json api spec expects dict, otherwise a list - # - http://jsonapi.org/format/#document-top-level - # The `results` key may be missing if unpaginated or an OPTIONS request + serializer = getattr(serializer_data, 'serializer', None) - resource_serializer = serializer_data.serializer + if serializer is not None: # Get the serializer fields - fields = utils.get_serializer_fields(resource_serializer) + fields = utils.get_serializer_fields(serializer) - json_api_data = list() - for position in range(len(serializer_data)): - resource = serializer_data[position] # Get current resource - resource_instance = resource_serializer.instance[position] # Get current instance + # Extract root meta for any type of serializer + json_api_meta.update(self.extract_root_meta(serializer, serializer_data)) - json_resource_obj = self.build_json_resource_obj(fields, resource, resource_instance, resource_name) - meta = self.extract_meta(resource_serializer, resource) - if meta: - json_resource_obj.update({'meta': utils.format_keys(meta)}) - json_api_meta = self.extract_root_meta(resource_serializer, resource, json_api_meta) - json_api_data.append(json_resource_obj) + if getattr(serializer, 'many', False): + json_api_data = list() - included = self.extract_included(fields, resource, resource_instance, included_resources) - if included: - json_api_included.extend(included) - else: - # Check if data contains a serializer - if hasattr(data, 'serializer'): - fields = utils.get_serializer_fields(data.serializer) - resource_instance = data.serializer.instance - json_api_data = self.build_json_resource_obj(fields, data, resource_instance, resource_name) + for position in range(len(serializer_data)): + resource = serializer_data[position] # Get current resource + resource_instance = serializer.instance[position] # Get current instance + + json_resource_obj = self.build_json_resource_obj(fields, resource, resource_instance, resource_name) + meta = self.extract_meta(serializer, resource) + if meta: + json_resource_obj.update({'meta': utils.format_keys(meta)}) + json_api_data.append(json_resource_obj) + + included = self.extract_included(fields, resource, resource_instance, included_resources) + if included: + json_api_included.extend(included) + else: + resource_instance = serializer.instance + json_api_data = self.build_json_resource_obj(fields, serializer_data, resource_instance, resource_name) - meta = self.extract_meta(data.serializer, data) + meta = self.extract_meta(serializer, serializer_data) if meta: json_api_data.update({'meta': utils.format_keys(meta)}) - json_api_meta = self.extract_root_meta(data.serializer, data, json_api_meta) - included = self.extract_included(fields, data, resource_instance, included_resources) + included = self.extract_included(fields, serializer_data, resource_instance, included_resources) if included: json_api_included.extend(included) - else: - json_api_data = data + # Make sure we render data in a specific order render_data = OrderedDict() From 21823ec5d22a285fde7e16280e9fd1c231d9c283 Mon Sep 17 00:00:00 2001 From: Scott Fisk Date: Fri, 8 Apr 2016 17:06:11 -0400 Subject: [PATCH 11/56] Fixed get_resource_name in case of non-model backed serializer. Closes #219 --- example/tests/unit/test_utils.py | 10 ++++++++++ rest_framework_json_api/utils.py | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/example/tests/unit/test_utils.py b/example/tests/unit/test_utils.py index 14ebd202..39d57428 100644 --- a/example/tests/unit/test_utils.py +++ b/example/tests/unit/test_utils.py @@ -15,6 +15,11 @@ pytestmark = pytest.mark.django_db +class NonModelResourceSerializer(serializers.Serializer): + class Meta: + resource_name = 'users' + + class ResourceSerializer(serializers.ModelSerializer): class Meta: fields = ('username',) @@ -51,6 +56,11 @@ def test_get_resource_name(): view.serializer_class.Meta.resource_name = 'rcustom' assert 'rcustom' == utils.get_resource_name(context), 'set on serializer' + view = GenericAPIView() + view.serializer_class = NonModelResourceSerializer + context = {'view': view} + assert 'users' == utils.get_resource_name(context), 'derived from non-model serializer' + def test_format_keys(): underscored = { diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index d8a4e67a..e0bc5740 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -214,10 +214,10 @@ def get_resource_type_from_manager(manager): def get_resource_type_from_serializer(serializer): - return getattr( - serializer.Meta, - 'resource_name', - get_resource_type_from_model(serializer.Meta.model)) + if hasattr(serializer.Meta, 'resource_name'): + return serializer.Meta.resource_name + else: + return get_resource_type_from_model(serializer.Meta.model) def get_included_serializers(serializer): From 63a2b361deaf6ee2667f1443c84ae66e9c0da98c Mon Sep 17 00:00:00 2001 From: Rollo Date: Wed, 4 Nov 2015 20:50:53 +0000 Subject: [PATCH 12/56] ResourceRelatedField now accepts serializer methods when many=True --- rest_framework_json_api/relations.py | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/rest_framework_json_api/relations.py b/rest_framework_json_api/relations.py index b7ccce36..1fd94d9b 100644 --- a/rest_framework_json_api/relations.py +++ b/rest_framework_json_api/relations.py @@ -9,6 +9,28 @@ get_resource_type_from_queryset, get_resource_type_from_instance, \ get_included_serializers, get_resource_type_from_serializer +import pdb + +JSONAPI_MANY_RELATION_KWARGS = ('model', ) + MANY_RELATION_KWARGS + +class ManyResourceRelatedField(ManyRelatedField): + """ + Allows us to use serializer method RelatedFields + with return querysets + """ + def __init__(self, child_relation=None, *args, **kwargs): + model = kwargs.pop('model', None) + if model: + self.model = model + super(ManyResourceRelatedField, self).__init__(child_relation, *args, **kwargs) + + def get_attribute(self, instance): + if self.source and hasattr(self.parent, self.source): + serializer_method = getattr(self.parent, self.source) + if hasattr(serializer_method, '__call__'): + return serializer_method(instance) + return super(ManyResourceRelatedField, self).get_attribute(instance) + class ResourceRelatedField(PrimaryKeyRelatedField): self_link_view_name = None @@ -25,6 +47,21 @@ class ResourceRelatedField(PrimaryKeyRelatedField): 'no_match': _('Invalid hyperlink - No URL match.'), } + def __new__(cls, *args, **kwargs): + # We override this because getting + # serializer methods fails when many is true + if kwargs.pop('many', False): + return cls.many_init(*args, **kwargs) + return super(ResourceRelatedField, cls).__new__(cls, *args, **kwargs) + + @classmethod + def many_init(cls, *args, **kwargs): + list_kwargs = {'child_relation': cls(*args, **kwargs)} + for key in kwargs.keys(): + if key in JSONAPI_MANY_RELATION_KWARGS: + list_kwargs[key] = kwargs[key] + return ManyResourceRelatedField(**list_kwargs) + def __init__(self, self_link_view_name=None, related_link_view_name=None, **kwargs): if self_link_view_name is not None: self.self_link_view_name = self_link_view_name From 0ed1667eb4837414cdfe8f31ef8cbf84678faa73 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Wed, 16 Mar 2016 07:37:28 -0500 Subject: [PATCH 13/56] Rename "suggested" posts to "featured" so we can use suggested as many=True --- example/serializers.py | 16 ++++++++-------- example/tests/integration/test_includes.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/serializers.py b/example/serializers.py index 61812337..10c0f95b 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -25,25 +25,25 @@ class EntrySerializer(serializers.ModelSerializer): def __init__(self, *args, **kwargs): # to make testing more concise we'll only output the - # `suggested` field when it's requested via `include` + # `featured` field when it's requested via `include` request = kwargs.get('context', {}).get('request') - if request and 'suggested' not in request.query_params.get('include', []): - self.fields.pop('suggested') + if request and 'featured' not in request.query_params.get('include', []): + self.fields.pop('featured') super(EntrySerializer, self).__init__(*args, **kwargs) included_serializers = { 'authors': 'example.serializers.AuthorSerializer', 'comments': 'example.serializers.CommentSerializer', - 'suggested': 'example.serializers.EntrySerializer', + 'featured': 'example.serializers.EntrySerializer', } body_format = serializers.SerializerMethodField() comments = relations.ResourceRelatedField( source='comment_set', many=True, read_only=True) - suggested = relations.SerializerMethodResourceRelatedField( - source='get_suggested', model=Entry, read_only=True) + featured = relations.SerializerMethodResourceRelatedField( + source='get_featured', model=Entry, read_only=True) - def get_suggested(self, obj): + def get_featured(self, obj): return Entry.objects.exclude(pk=obj.pk).first() def get_body_format(self, obj): @@ -52,7 +52,7 @@ def get_body_format(self, obj): class Meta: model = Entry fields = ('blog', 'headline', 'body_text', 'pub_date', 'mod_date', - 'authors', 'comments', 'suggested',) + 'authors', 'comments', 'featured',) meta_fields = ('body_format',) diff --git a/example/tests/integration/test_includes.py b/example/tests/integration/test_includes.py index 8c4cb587..05c59131 100644 --- a/example/tests/integration/test_includes.py +++ b/example/tests/integration/test_includes.py @@ -31,7 +31,7 @@ def test_included_data_on_detail(single_entry, client): def test_dynamic_related_data_is_included(single_entry, entry_factory, client): entry_factory() - response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + '?include=suggested') + response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + '?include=featured') included = load_json(response.content).get('included') assert [x.get('type') for x in included] == ['entries'], 'Dynamic included types are incorrect' From 72feb475db0d970477ae72e1e20ea99e284dda8a Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Tue, 12 Apr 2016 12:37:27 -0500 Subject: [PATCH 14/56] Updated SerializerMethodResourceRelatedField to allow many=True Issue #151 Closes #220 --- example/serializers.py | 10 ++- .../test_non_paginated_responses.py | 6 ++ example/tests/integration/test_pagination.py | 3 + rest_framework_json_api/relations.py | 79 ++++++++++--------- 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/example/serializers.py b/example/serializers.py index 10c0f95b..e259a10b 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -38,11 +38,19 @@ def __init__(self, *args, **kwargs): } body_format = serializers.SerializerMethodField() + # many related from model comments = relations.ResourceRelatedField( source='comment_set', many=True, read_only=True) + # many related from serializer + suggested = relations.SerializerMethodResourceRelatedField( + source='get_suggested', model=Entry, many=True, read_only=True) + # single related from serializer featured = relations.SerializerMethodResourceRelatedField( source='get_featured', model=Entry, read_only=True) + def get_suggested(self, obj): + return Entry.objects.exclude(pk=obj.pk) + def get_featured(self, obj): return Entry.objects.exclude(pk=obj.pk).first() @@ -52,7 +60,7 @@ def get_body_format(self, obj): class Meta: model = Entry fields = ('blog', 'headline', 'body_text', 'pub_date', 'mod_date', - 'authors', 'comments', 'featured',) + 'authors', 'comments', 'featured', 'suggested',) meta_fields = ('body_format',) diff --git a/example/tests/integration/test_non_paginated_responses.py b/example/tests/integration/test_non_paginated_responses.py index f68f2b71..de9e3055 100644 --- a/example/tests/integration/test_non_paginated_responses.py +++ b/example/tests/integration/test_non_paginated_responses.py @@ -41,6 +41,9 @@ def test_multiple_entries_no_pagination(multiple_entries, rf): "comments": { "meta": {"count": 1}, "data": [{"type": "comments", "id": "1"}] + }, + "suggested": { + "data": [{"type": "entries", "id": "2"}] } } }, @@ -69,6 +72,9 @@ def test_multiple_entries_no_pagination(multiple_entries, rf): "comments": { "meta": {"count": 1}, "data": [{"type": "comments", "id": "2"}] + }, + "suggested": { + "data": [{"type": "entries", "id": "1"}] } } }, diff --git a/example/tests/integration/test_pagination.py b/example/tests/integration/test_pagination.py index 0cc5e15e..742be523 100644 --- a/example/tests/integration/test_pagination.py +++ b/example/tests/integration/test_pagination.py @@ -35,6 +35,9 @@ def test_pagination_with_single_entry(single_entry, client): "comments": { "meta": {"count": 1}, "data": [{"type": "comments", "id": "1"}] + }, + "suggested": { + "data": [] } } }], diff --git a/rest_framework_json_api/relations.py b/rest_framework_json_api/relations.py index 1fd94d9b..0e6594d5 100644 --- a/rest_framework_json_api/relations.py +++ b/rest_framework_json_api/relations.py @@ -3,34 +3,13 @@ from rest_framework.fields import MISSING_ERROR_MESSAGE from rest_framework.relations import * from django.utils.translation import ugettext_lazy as _ +from django.db.models.query import QuerySet from rest_framework_json_api.exceptions import Conflict from rest_framework_json_api.utils import Hyperlink, \ get_resource_type_from_queryset, get_resource_type_from_instance, \ get_included_serializers, get_resource_type_from_serializer -import pdb - -JSONAPI_MANY_RELATION_KWARGS = ('model', ) + MANY_RELATION_KWARGS - -class ManyResourceRelatedField(ManyRelatedField): - """ - Allows us to use serializer method RelatedFields - with return querysets - """ - def __init__(self, child_relation=None, *args, **kwargs): - model = kwargs.pop('model', None) - if model: - self.model = model - super(ManyResourceRelatedField, self).__init__(child_relation, *args, **kwargs) - - def get_attribute(self, instance): - if self.source and hasattr(self.parent, self.source): - serializer_method = getattr(self.parent, self.source) - if hasattr(serializer_method, '__call__'): - return serializer_method(instance) - return super(ManyResourceRelatedField, self).get_attribute(instance) - class ResourceRelatedField(PrimaryKeyRelatedField): self_link_view_name = None @@ -47,21 +26,6 @@ class ResourceRelatedField(PrimaryKeyRelatedField): 'no_match': _('Invalid hyperlink - No URL match.'), } - def __new__(cls, *args, **kwargs): - # We override this because getting - # serializer methods fails when many is true - if kwargs.pop('many', False): - return cls.many_init(*args, **kwargs) - return super(ResourceRelatedField, cls).__new__(cls, *args, **kwargs) - - @classmethod - def many_init(cls, *args, **kwargs): - list_kwargs = {'child_relation': cls(*args, **kwargs)} - for key in kwargs.keys(): - if key in JSONAPI_MANY_RELATION_KWARGS: - list_kwargs[key] = kwargs[key] - return ManyResourceRelatedField(**list_kwargs) - def __init__(self, self_link_view_name=None, related_link_view_name=None, **kwargs): if self_link_view_name is not None: self.self_link_view_name = self_link_view_name @@ -205,11 +169,50 @@ def choices(self): ]) + class SerializerMethodResourceRelatedField(ResourceRelatedField): + """ + Allows us to use serializer method RelatedFields + with return querysets + """ + def __new__(cls, *args, **kwargs): + """ + We override this because getting serializer methods + fails at the base class when many=True + """ + if kwargs.pop('many', False): + return cls.many_init(*args, **kwargs) + return super(ResourceRelatedField, cls).__new__(cls, *args, **kwargs) + + def __init__(self, child_relation=None, *args, **kwargs): + # DRF 3.1 doesn't expect the `many` kwarg + kwargs.pop('many', None) + model = kwargs.pop('model', None) + if model: + self.model = model + super(SerializerMethodResourceRelatedField, self).__init__(child_relation, *args, **kwargs) + + @classmethod + def many_init(cls, *args, **kwargs): + list_kwargs = {'child_relation': cls(*args, **kwargs)} + for key in kwargs.keys(): + if key in ('model',) + MANY_RELATION_KWARGS: + list_kwargs[key] = kwargs[key] + return SerializerMethodResourceRelatedField(**list_kwargs) + def get_attribute(self, instance): # check for a source fn defined on the serializer instead of the model if self.source and hasattr(self.parent, self.source): serializer_method = getattr(self.parent, self.source) if hasattr(serializer_method, '__call__'): return serializer_method(instance) - return super(ResourceRelatedField, self).get_attribute(instance) + return super(SerializerMethodResourceRelatedField, self).get_attribute(instance) + + def to_representation(self, value): + if isinstance(value, QuerySet): + base = super(SerializerMethodResourceRelatedField, self) + return [base.to_representation(x) for x in value] + return super(SerializerMethodResourceRelatedField, self).to_representation(value) + + def get_links(self, obj=None, lookup_field='pk'): + return OrderedDict() From d174b3a1ba02f0ee18c18a3065770eb4051b241c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Mali=C5=84ski?= Date: Thu, 14 Apr 2016 14:40:27 +0200 Subject: [PATCH 15/56] Correct error responses for projects with different DRF-configurations (#222) * [#214] Add error messages tests. * [#214] Extract formatting DRF errors. * Add example view with custom handle_exception. * Use HTTP 422 for validation error responses. * Add full example of class-configured json api view. --- example/tests/test_views.py | 35 ++++++++++++++++ example/views.py | 44 ++++++++++++++++++++ rest_framework_json_api/exceptions.py | 60 +-------------------------- rest_framework_json_api/utils.py | 58 ++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 58 deletions(-) diff --git a/example/tests/test_views.py b/example/tests/test_views.py index c8221077..a76df044 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -1,13 +1,18 @@ import json +from django.test import RequestFactory from django.utils import timezone from rest_framework.reverse import reverse from rest_framework.test import APITestCase +from rest_framework.test import force_authenticate from rest_framework_json_api.utils import format_relation_name from example.models import Blog, Entry, Comment, Author +from .. import views +from . import TestBase + class TestRelationshipView(APITestCase): def setUp(self): @@ -184,3 +189,33 @@ def test_delete_to_many_relationship_with_change(self): } response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() + + +class TestValidationErrorResponses(TestBase): + def test_if_returns_error_on_empty_post(self): + view = views.BlogViewSet.as_view({'post': 'create'}) + response = self._get_create_response("{}", view) + self.assertEqual(400, response.status_code) + expected = [{'detail': 'Received document does not contain primary data', 'status': '400', 'source': {'pointer': '/data'}}] + self.assertEqual(expected, response.data) + + def test_if_returns_error_on_missing_form_data_post(self): + view = views.BlogViewSet.as_view({'post': 'create'}) + response = self._get_create_response('{"data":{"attributes":{},"type":"blogs"}}', view) + self.assertEqual(400, response.status_code) + expected = [{'status': '400', 'detail': 'This field is required.', 'source': {'pointer': '/data/attributes/name'}}] + self.assertEqual(expected, response.data) + + def test_if_returns_error_on_bad_endpoint_name(self): + view = views.BlogViewSet.as_view({'post': 'create'}) + response = self._get_create_response('{"data":{"attributes":{},"type":"bad"}}', view) + self.assertEqual(409, response.status_code) + expected = [{'detail': "The resource object's type (bad) is not the type that constitute the collection represented by the endpoint (blogs).", 'source': {'pointer': '/data'}, 'status': '409'}] + self.assertEqual(expected, response.data) + + def _get_create_response(self, data, view): + factory = RequestFactory() + request = factory.post('/', data, content_type='application/vnd.api+json') + user = self.create_user('user', 'pass') + force_authenticate(request, user) + return view(request) diff --git a/example/views.py b/example/views.py index c8dddc50..988cda66 100644 --- a/example/views.py +++ b/example/views.py @@ -1,15 +1,59 @@ +from rest_framework import exceptions from rest_framework import viewsets +import rest_framework.parsers +import rest_framework.renderers +import rest_framework_json_api.metadata +import rest_framework_json_api.parsers +import rest_framework_json_api.renderers from rest_framework_json_api.views import RelationshipView from example.models import Blog, Entry, Author, Comment from example.serializers import ( BlogSerializer, EntrySerializer, AuthorSerializer, CommentSerializer) +from rest_framework_json_api.utils import format_drf_errors + +HTTP_422_UNPROCESSABLE_ENTITY = 422 + class BlogViewSet(viewsets.ModelViewSet): queryset = Blog.objects.all() serializer_class = BlogSerializer +class JsonApiViewSet(viewsets.ModelViewSet): + """ + This is an example on how to configure DRF-jsonapi from + within a class. It allows using DRF-jsonapi alongside + vanilla DRF API views. + """ + parser_classes = [ + rest_framework_json_api.parsers.JSONParser, + rest_framework.parsers.FormParser, + rest_framework.parsers.MultiPartParser, + ] + renderer_classes = [ + rest_framework_json_api.renderers.JSONRenderer, + rest_framework.renderers.BrowsableAPIRenderer, + ] + metadata_class = rest_framework_json_api.metadata.JSONAPIMetadata + + def handle_exception(self, exc): + if isinstance(exc, exceptions.ValidationError): + # some require that validation errors return 422 status + # for example ember-data (isInvalid method on adapter) + exc.status_code = HTTP_422_UNPROCESSABLE_ENTITY + # exception handler can't be set on class so you have to + # override the error response in this method + response = super(JsonApiViewSet, self).handle_exception(exc) + context = self.get_exception_handler_context() + return format_drf_errors(response, context, exc) + + +class BlogCustomViewSet(JsonApiViewSet): + queryset = Blog.objects.all() + serializer_class = BlogSerializer + + class EntryViewSet(viewsets.ModelViewSet): queryset = Entry.objects.all() resource_name = 'posts' diff --git a/rest_framework_json_api/exceptions.py b/rest_framework_json_api/exceptions.py index 935fecdb..c581bda2 100644 --- a/rest_framework_json_api/exceptions.py +++ b/rest_framework_json_api/exceptions.py @@ -1,9 +1,7 @@ -import inspect -from django.utils import six, encoding from django.utils.translation import ugettext_lazy as _ from rest_framework import status, exceptions -from rest_framework_json_api.utils import format_value +from rest_framework_json_api import utils def exception_handler(exc, context): @@ -18,63 +16,9 @@ def exception_handler(exc, context): if not response: return response - - errors = [] - # handle generic errors. ValidationError('test') in a view for example - if isinstance(response.data, list): - for message in response.data: - errors.append({ - 'detail': message, - 'source': { - 'pointer': '/data', - }, - 'status': encoding.force_text(response.status_code), - }) - # handle all errors thrown from serializers - else: - for field, error in response.data.items(): - field = format_value(field) - pointer = '/data/attributes/{}'.format(field) - # see if they passed a dictionary to ValidationError manually - if isinstance(error, dict): - errors.append(error) - elif isinstance(error, six.string_types): - classes = inspect.getmembers(exceptions, inspect.isclass) - # DRF sets the `field` to 'detail' for its own exceptions - if isinstance(exc, tuple(x[1] for x in classes)): - pointer = '/data' - errors.append({ - 'detail': error, - 'source': { - 'pointer': pointer, - }, - 'status': encoding.force_text(response.status_code), - }) - elif isinstance(error, list): - for message in error: - errors.append({ - 'detail': message, - 'source': { - 'pointer': pointer, - }, - 'status': encoding.force_text(response.status_code), - }) - else: - errors.append({ - 'detail': error, - 'source': { - 'pointer': pointer, - }, - 'status': encoding.force_text(response.status_code), - }) - - - context['view'].resource_name = 'errors' - response.data = errors - return response + return utils.format_drf_errors(response, context, exc) class Conflict(exceptions.APIException): status_code = status.HTTP_409_CONFLICT default_detail = _('Conflict.') - diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index e0bc5740..ff0e8953 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -3,13 +3,16 @@ """ import copy from collections import OrderedDict +import inspect import inflection from django.conf import settings +from django.utils import encoding from django.utils import six from django.utils.module_loading import import_string as import_class_from_dotted_path from django.utils.translation import ugettext_lazy as _ from rest_framework.exceptions import APIException +from rest_framework import exceptions try: from rest_framework.serializers import ManyRelatedField @@ -249,3 +252,58 @@ def __new__(self, url, name): return ret is_hyperlink = True + + +def format_drf_errors(response, context, exc): + errors = [] + # handle generic errors. ValidationError('test') in a view for example + if isinstance(response.data, list): + for message in response.data: + errors.append({ + 'detail': message, + 'source': { + 'pointer': '/data', + }, + 'status': encoding.force_text(response.status_code), + }) + # handle all errors thrown from serializers + else: + for field, error in response.data.items(): + field = format_value(field) + pointer = '/data/attributes/{}'.format(field) + # see if they passed a dictionary to ValidationError manually + if isinstance(error, dict): + errors.append(error) + elif isinstance(error, six.string_types): + classes = inspect.getmembers(exceptions, inspect.isclass) + # DRF sets the `field` to 'detail' for its own exceptions + if isinstance(exc, tuple(x[1] for x in classes)): + pointer = '/data' + errors.append({ + 'detail': error, + 'source': { + 'pointer': pointer, + }, + 'status': encoding.force_text(response.status_code), + }) + elif isinstance(error, list): + for message in error: + errors.append({ + 'detail': message, + 'source': { + 'pointer': pointer, + }, + 'status': encoding.force_text(response.status_code), + }) + else: + errors.append({ + 'detail': error, + 'source': { + 'pointer': pointer, + }, + 'status': encoding.force_text(response.status_code), + }) + + context['view'].resource_name = 'errors' + response.data = errors + return response From 3934ba2ee96fa2eea45bca388352a90011b6c8c6 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Fri, 15 Apr 2016 11:06:23 -0500 Subject: [PATCH 16/56] Fixed naming that suggested settings were used to inflect relationship names. JSON_API_FORMAT_RELATION_NAME actually inflected the `type` instead. The relation name is not changable at this time although if it woudl be useful to someone it would be fine to implement it. Closes #136. --- docs/usage.md | 15 ++++++--------- example/settings/dev.py | 2 +- example/settings/test.py | 4 ++-- example/tests/test_relations.py | 12 ++++++------ example/tests/test_serializers.py | 12 ++++++------ example/tests/test_views.py | 28 ++++++++++++++-------------- example/tests/unit/test_utils.py | 10 +++++----- rest_framework_json_api/renderers.py | 4 ++-- rest_framework_json_api/utils.py | 17 +++++++++++++---- 9 files changed, 55 insertions(+), 49 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index c4879956..1b8a7e68 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -155,12 +155,12 @@ Example - With format conversion set to `dasherize`: } ``` -#### Relationship types +#### Types -A similar option to JSON\_API\_FORMAT\_RELATION\_KEYS can be set for the relationship names: +A similar option to JSON\_API\_FORMAT\_KEYS can be set for the types: ``` python -JSON_API_FORMAT_RELATION_KEYS = 'dasherize' +JSON_API_FORMAT_TYPES = 'dasherize' ``` Example without format conversion: @@ -168,7 +168,7 @@ Example without format conversion: ``` js { "data": [{ - "type": "identities", + "type": "blog_identity", "id": 3, "attributes": { ... @@ -191,7 +191,7 @@ When set to dasherize: ``` js { "data": [{ - "type": "identities", + "type": "blog-identity", "id": 3, "attributes": { ... @@ -210,7 +210,7 @@ When set to dasherize: It is also possible to pluralize the types like so: ```python -JSON_API_PLURALIZE_RELATION_TYPE = True +JSON_API_PLURALIZE_TYPES = True ``` Example without pluralization: @@ -257,9 +257,6 @@ When set to pluralize: } ``` -Both `JSON_API_PLURALIZE_RELATION_TYPE` and `JSON_API_FORMAT_RELATION_KEYS` can be combined to -achieve different results. - ### Related fields Because of the additional structure needed to represent relationships in JSON diff --git a/example/settings/dev.py b/example/settings/dev.py index e35ea803..b4b435ca 100644 --- a/example/settings/dev.py +++ b/example/settings/dev.py @@ -37,7 +37,7 @@ MIDDLEWARE_CLASSES = () JSON_API_FORMAT_KEYS = 'camelize' -JSON_API_FORMAT_RELATION_KEYS = 'camelize' +JSON_API_FORMAT_TYPES = 'camelize' REST_FRAMEWORK = { 'PAGE_SIZE': 5, 'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler', diff --git a/example/settings/test.py b/example/settings/test.py index d67c5e45..5bb3f45d 100644 --- a/example/settings/test.py +++ b/example/settings/test.py @@ -10,8 +10,8 @@ ROOT_URLCONF = 'example.urls_test' JSON_API_FORMAT_KEYS = 'camelize' -JSON_API_FORMAT_RELATION_KEYS = 'camelize' -JSON_API_PLURALIZE_RELATION_TYPE = True +JSON_API_FORMAT_TYPES = 'camelize' +JSON_API_PLURALIZE_TYPES = True REST_FRAMEWORK.update({ 'PAGE_SIZE': 1, }) diff --git a/example/tests/test_relations.py b/example/tests/test_relations.py index 1fe5b537..adbf4984 100644 --- a/example/tests/test_relations.py +++ b/example/tests/test_relations.py @@ -5,7 +5,7 @@ from . import TestBase from rest_framework_json_api.exceptions import Conflict -from rest_framework_json_api.utils import format_relation_name +from rest_framework_json_api.utils import format_resource_type from example.models import Blog, Entry, Comment, Author from example.serializers import CommentSerializer from rest_framework_json_api.relations import ResourceRelatedField @@ -42,7 +42,7 @@ def test_data_in_correct_format_when_instantiated_with_blog_object(self): serializer = BlogFKSerializer(instance={'blog': self.blog}) expected_data = { - 'type': format_relation_name('Blog'), + 'type': format_resource_type('Blog'), 'id': str(self.blog.id) } @@ -54,7 +54,7 @@ def test_data_in_correct_format_when_instantiated_with_entry_object(self): serializer = EntryFKSerializer(instance={'entry': self.entry}) expected_data = { - 'type': format_relation_name('Entry'), + 'type': format_resource_type('Entry'), 'id': str(self.entry.id) } @@ -65,7 +65,7 @@ def test_data_in_correct_format_when_instantiated_with_entry_object(self): def test_deserialize_primitive_data_blog(self): serializer = BlogFKSerializer(data={ 'blog': { - 'type': format_relation_name('Blog'), + 'type': format_resource_type('Blog'), 'id': str(self.blog.id) } } @@ -90,7 +90,7 @@ def test_validation_fails_for_wrong_type(self): def test_serialize_many_to_many_relation(self): serializer = EntryModelSerializer(instance=self.entry) - type_string = format_relation_name('Author') + type_string = format_resource_type('Author') author_pks = Author.objects.values_list('pk', flat=True) expected_data = [{'type': type_string, 'id': str(pk)} for pk in author_pks] @@ -100,7 +100,7 @@ def test_serialize_many_to_many_relation(self): ) def test_deserialize_many_to_many_relation(self): - type_string = format_relation_name('Author') + type_string = format_resource_type('Author') author_pks = Author.objects.values_list('pk', flat=True) authors = [{'type': type_string, 'id': pk} for pk in author_pks] diff --git a/example/tests/test_serializers.py b/example/tests/test_serializers.py index d0aa7177..df556050 100644 --- a/example/tests/test_serializers.py +++ b/example/tests/test_serializers.py @@ -2,7 +2,7 @@ from django.test import TestCase from django.utils import timezone -from rest_framework_json_api.utils import format_relation_name +from rest_framework_json_api.utils import format_resource_type from rest_framework_json_api.serializers import ResourceIdentifierObjectSerializer from example.models import Blog, Entry, Author @@ -35,20 +35,20 @@ def setUp(self): def test_data_in_correct_format_when_instantiated_with_blog_object(self): serializer = ResourceIdentifierObjectSerializer(instance=self.blog) - expected_data = {'type': format_relation_name('Blog'), 'id': str(self.blog.id)} + expected_data = {'type': format_resource_type('Blog'), 'id': str(self.blog.id)} assert serializer.data == expected_data def test_data_in_correct_format_when_instantiated_with_entry_object(self): serializer = ResourceIdentifierObjectSerializer(instance=self.entry) - expected_data = {'type': format_relation_name('Entry'), 'id': str(self.entry.id)} + expected_data = {'type': format_resource_type('Entry'), 'id': str(self.entry.id)} assert serializer.data == expected_data def test_deserialize_primitive_data_blog(self): initial_data = { - 'type': format_relation_name('Blog'), + 'type': format_resource_type('Blog'), 'id': str(self.blog.id) } serializer = ResourceIdentifierObjectSerializer(data=initial_data, model_class=Blog) @@ -60,14 +60,14 @@ def test_data_in_correct_format_when_instantiated_with_queryset(self): qs = Author.objects.all() serializer = ResourceIdentifierObjectSerializer(instance=qs, many=True) - type_string = format_relation_name('Author') + type_string = format_resource_type('Author') author_pks = Author.objects.values_list('pk', flat=True) expected_data = [{'type': type_string, 'id': str(pk)} for pk in author_pks] assert serializer.data == expected_data def test_deserialize_many(self): - type_string = format_relation_name('Author') + type_string = format_resource_type('Author') author_pks = Author.objects.values_list('pk', flat=True) initial_data = [{'type': type_string, 'id': str(pk)} for pk in author_pks] diff --git a/example/tests/test_views.py b/example/tests/test_views.py index c8221077..c90ecedc 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -5,7 +5,7 @@ from rest_framework.test import APITestCase -from rest_framework_json_api.utils import format_relation_name +from rest_framework_json_api.utils import format_resource_type from example.models import Blog, Entry, Comment, Author @@ -44,7 +44,7 @@ def setUp(self): def test_get_entry_relationship_blog(self): url = reverse('entry-relationships', kwargs={'pk': self.first_entry.id, 'related_field': 'blog'}) response = self.client.get(url) - expected_data = {'type': format_relation_name('Blog'), 'id': str(self.first_entry.blog.id)} + expected_data = {'type': format_resource_type('Blog'), 'id': str(self.first_entry.blog.id)} assert response.data == expected_data @@ -55,8 +55,8 @@ def test_get_entry_relationship_invalid_field(self): def test_get_blog_relationship_entry_set(self): response = self.client.get('/blogs/{}/relationships/entry_set'.format(self.blog.id)) - expected_data = [{'type': format_relation_name('Entry'), 'id': str(self.first_entry.id)}, - {'type': format_relation_name('Entry'), 'id': str(self.second_entry.id)}] + expected_data = [{'type': format_resource_type('Entry'), 'id': str(self.first_entry.id)}, + {'type': format_resource_type('Entry'), 'id': str(self.second_entry.id)}] assert response.data == expected_data @@ -85,14 +85,14 @@ def test_get_to_many_relationship_self_link(self): response = self.client.get(url) expected_data = { 'links': {'self': 'http://testserver/authors/1/relationships/comment_set'}, - 'data': [{'id': str(self.second_comment.id), 'type': format_relation_name('Comment')}] + 'data': [{'id': str(self.second_comment.id), 'type': format_resource_type('Comment')}] } assert json.loads(response.content.decode('utf-8')) == expected_data def test_patch_to_one_relationship(self): url = '/entries/{}/relationships/blog'.format(self.first_entry.id) request_data = { - 'data': {'type': format_relation_name('Blog'), 'id': str(self.other_blog.id)} + 'data': {'type': format_resource_type('Blog'), 'id': str(self.other_blog.id)} } response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() @@ -103,7 +103,7 @@ def test_patch_to_one_relationship(self): def test_patch_to_many_relationship(self): url = '/blogs/{}/relationships/entry_set'.format(self.first_entry.id) request_data = { - 'data': [{'type': format_relation_name('Entry'), 'id': str(self.first_entry.id)}, ] + 'data': [{'type': format_resource_type('Entry'), 'id': str(self.first_entry.id)}, ] } response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() @@ -114,7 +114,7 @@ def test_patch_to_many_relationship(self): def test_post_to_one_relationship_should_fail(self): url = '/entries/{}/relationships/blog'.format(self.first_entry.id) request_data = { - 'data': {'type': format_relation_name('Blog'), 'id': str(self.other_blog.id)} + 'data': {'type': format_resource_type('Blog'), 'id': str(self.other_blog.id)} } response = self.client.post(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 405, response.content.decode() @@ -122,7 +122,7 @@ def test_post_to_one_relationship_should_fail(self): def test_post_to_many_relationship_with_no_change(self): url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id) request_data = { - 'data': [{'type': format_relation_name('Comment'), 'id': str(self.first_comment.id)}, ] + 'data': [{'type': format_resource_type('Comment'), 'id': str(self.first_comment.id)}, ] } response = self.client.post(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 204, response.content.decode() @@ -130,7 +130,7 @@ def test_post_to_many_relationship_with_no_change(self): def test_post_to_many_relationship_with_change(self): url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id) request_data = { - 'data': [{'type': format_relation_name('Comment'), 'id': str(self.second_comment.id)}, ] + 'data': [{'type': format_resource_type('Comment'), 'id': str(self.second_comment.id)}, ] } response = self.client.post(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() @@ -140,7 +140,7 @@ def test_post_to_many_relationship_with_change(self): def test_delete_to_one_relationship_should_fail(self): url = '/entries/{}/relationships/blog'.format(self.first_entry.id) request_data = { - 'data': {'type': format_relation_name('Blog'), 'id': str(self.other_blog.id)} + 'data': {'type': format_resource_type('Blog'), 'id': str(self.other_blog.id)} } response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 405, response.content.decode() @@ -164,7 +164,7 @@ def test_delete_relationship_overriding_with_none(self): def test_delete_to_many_relationship_with_no_change(self): url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id) request_data = { - 'data': [{'type': format_relation_name('Comment'), 'id': str(self.second_comment.id)}, ] + 'data': [{'type': format_resource_type('Comment'), 'id': str(self.second_comment.id)}, ] } response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 204, response.content.decode() @@ -172,7 +172,7 @@ def test_delete_to_many_relationship_with_no_change(self): def test_delete_one_to_many_relationship_with_not_null_constraint(self): url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id) request_data = { - 'data': [{'type': format_relation_name('Comment'), 'id': str(self.first_comment.id)}, ] + 'data': [{'type': format_resource_type('Comment'), 'id': str(self.first_comment.id)}, ] } response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 409, response.content.decode() @@ -180,7 +180,7 @@ def test_delete_one_to_many_relationship_with_not_null_constraint(self): def test_delete_to_many_relationship_with_change(self): url = '/authors/{}/relationships/comment_set'.format(self.author.id) request_data = { - 'data': [{'type': format_relation_name('Comment'), 'id': str(self.second_comment.id)}, ] + 'data': [{'type': format_resource_type('Comment'), 'id': str(self.second_comment.id)}, ] } response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() diff --git a/example/tests/unit/test_utils.py b/example/tests/unit/test_utils.py index 39d57428..92b12010 100644 --- a/example/tests/unit/test_utils.py +++ b/example/tests/unit/test_utils.py @@ -29,11 +29,11 @@ class Meta: def test_get_resource_name(): view = APIView() context = {'view': view} - setattr(settings, 'JSON_API_FORMAT_RELATION_KEYS', None) + setattr(settings, 'JSON_API_FORMAT_TYPES', None) assert 'APIViews' == utils.get_resource_name(context), 'not formatted' context = {'view': view} - setattr(settings, 'JSON_API_FORMAT_RELATION_KEYS', 'dasherize') + setattr(settings, 'JSON_API_FORMAT_TYPES', 'dasherize') assert 'api-views' == utils.get_resource_name(context), 'derived from view' view.model = get_user_model() @@ -91,9 +91,9 @@ def test_format_value(): assert utils.format_value('first-name', 'underscore') == 'first_name' -def test_format_relation_name(): - assert utils.format_relation_name('first_name', 'capitalize') == 'FirstNames' - assert utils.format_relation_name('first_name', 'camelize') == 'firstNames' +def test_format_resource_type(): + assert utils.format_resource_type('first_name', 'capitalize') == 'FirstNames' + assert utils.format_resource_type('first_name', 'camelize') == 'firstNames' class SerializerWithIncludedSerializers(EntrySerializer): diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index ac0517b9..518b653e 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -208,7 +208,7 @@ def extract_relationships(fields, resource, resource_instance): if isinstance(field, ModelSerializer): relation_model = field.Meta.model - relation_type = utils.format_relation_name(relation_model.__name__) + relation_type = utils.format_type(relation_model.__name__) data.update({ field_name: { @@ -343,7 +343,7 @@ def extract_root_meta(serializer, resource): if hasattr(serializer, 'child'): many = True serializer = serializer.child - + data = {} if getattr(serializer, 'get_root_meta', None): json_api_meta = serializer.get_root_meta(resource, many) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index e0bc5740..9c6a331b 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -2,6 +2,7 @@ Utils. """ import copy +import warnings from collections import OrderedDict import inflection @@ -59,7 +60,7 @@ def get_resource_name(context): return resource_name # the name was calculated automatically from the view > pluralize and format - resource_name = format_relation_name(resource_name) + resource_name = format_resource_type(resource_name) return resource_name @@ -137,10 +138,18 @@ def format_value(value, format_type=None): def format_relation_name(value, format_type=None): + warnings.warn("The 'format_relation_name' function has been renamed 'format_resource_type' and the settings are now 'JSON_API_FORMAT_TYPES' and 'JSON_API_PLURALIZE_TYPES'") if format_type is None: - format_type = getattr(settings, 'JSON_API_FORMAT_RELATION_KEYS', False) + format_type = getattr(settings, 'JSON_API_FORMAT_RELATION_KEYS', None) + pluralize = getattr(settings, 'JSON_API_PLURALIZE_RELATION_TYPE', None) + return format_resource_type(value, format_type, pluralize) - pluralize = getattr(settings, 'JSON_API_PLURALIZE_RELATION_TYPE', False) +def format_resource_type(value, format_type=None, pluralize=None): + if format_type is None: + format_type = getattr(settings, 'JSON_API_FORMAT_TYPES', False) + + if pluralize is None: + pluralize = getattr(settings, 'JSON_API_PLURALIZE_TYPES', False) if format_type: # format_type will never be None here so we can use format_value @@ -198,7 +207,7 @@ def get_resource_type_from_model(model): return getattr( json_api_meta, 'resource_name', - format_relation_name(model.__name__)) + format_resource_type(model.__name__)) def get_resource_type_from_queryset(qs): From 58bd785fbb04f191862f9249bdb0d1ba7515bbef Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Fri, 15 Apr 2016 11:23:21 -0500 Subject: [PATCH 17/56] Updated changelog --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67c2d76d..885a1b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ +v2.0.0 + +* Renamed `JSON_API_FORMAT_RELATION_KEYS` to `JSON_API_FORMAT_TYPES` to match what it was actually doing +* Renamed `JSON_API_PLURALIZE_RELATION_TYPE` to `JSON_API_PLURALIZE_TYPES` +* Documented ResourceRelatedField and RelationshipView +* Added LimitOffsetPagination +* Support deeply nested `?includes=foo.bar.baz` without returning intermediate models (bar) +* Allow a view's serializer_class to be fetched at runtime via `get_serializer_class` +* Added support for `get_root_meta` on list serializers + + v2.0.0-beta.2 * Added JSONAPIMeta class option to models for overriding `resource_name`. #197 From 05d8ef48e3660f0e3474e970c6a69d4332264f5c Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Fri, 15 Apr 2016 12:09:01 -0500 Subject: [PATCH 18/56] Added a doc note to prefer setting resource_name on serializers or models. Closes #207 --- docs/usage.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 1b8a7e68..e815762c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -87,7 +87,10 @@ class Me(models.Model): If you set the `resource_name` on a combination of model, serializer, or view in the same hierarchy, the name will be resolved as following: view > serializer > model. (Ex: A view `resource_name` will always override a -`resource_name` specified on a serializer or model) +`resource_name` specified on a serializer or model). Setting the `resource_name` +on the view should be used sparingly as serializers and models are shared between +multiple endpoints. Setting the `resource_name` on views may result in a different +`type` being set depending on which endpoint the resource is fetched from. ### Inflecting object and relation keys From bb26764837e383d1d09bc1449eaf21db2e2bb86e Mon Sep 17 00:00:00 2001 From: Anton Shutik Date: Mon, 18 Apr 2016 15:44:36 +0300 Subject: [PATCH 19/56] Added get_related_field_name method to RelationshipView * Added get_related_field_name method to RelationshipView * Added docs about field_name_mapping --- docs/usage.md | 9 +++++++++ rest_framework_json_api/views.py | 13 ++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index e815762c..27caee0c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -413,6 +413,15 @@ model field `Order.line_items` on the Order with pk 3, the url would be `self_link_view_name` keyword argument, which should match the `name=` provided in the urlconf, and will use the name of the field for the `related_field` kwarg. +Also we can override `related_field` in the url. Let's say we want the url to be: +`/order/3/relationships/order_items` - all we need to do is just add `field_name_mapping` +dict to the class: +```python +field_name_mapping = { + 'line_items': 'order_items' + } +``` + ### Meta diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index a43fad89..4b6e631a 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -19,6 +19,7 @@ class RelationshipView(generics.GenericAPIView): serializer_class = ResourceIdentifierObjectSerializer self_link_view_name = None related_link_view_name = None + field_name_mapping = {} def get_serializer_class(self): if getattr(self, 'action', False) is None: @@ -96,7 +97,7 @@ def patch(self, request, *args, **kwargs): related_model_class = related_instance_or_manager.__class__ serializer = self.get_serializer(data=request.data, model_class=related_model_class) serializer.is_valid(raise_exception=True) - setattr(parent_obj, kwargs['related_field'], serializer.validated_data) + setattr(parent_obj, self.get_related_field_name(), serializer.validated_data) parent_obj.save() result_serializer = self._instantiate_serializer(related_instance_or_manager) return Response(result_serializer.data) @@ -138,10 +139,16 @@ def delete(self, request, *args, **kwargs): def get_related_instance(self): try: - return getattr(self.get_object(), self.kwargs['related_field']) + return getattr(self.get_object(), self.get_related_field_name()) except AttributeError: raise NotFound + def get_related_field_name(self): + field_name = self.kwargs['related_field'] + if field_name in self.field_name_mapping: + return self.field_name_mapping[field_name] + return field_name + def _instantiate_serializer(self, instance): if isinstance(instance, Model) or instance is None: return self.get_serializer(instance=instance) @@ -153,7 +160,7 @@ def _instantiate_serializer(self, instance): def get_resource_name(self): if not hasattr(self, '_resource_name'): - instance = getattr(self.get_object(), self.kwargs['related_field']) + instance = getattr(self.get_object(), self.get_related_field_name()) self._resource_name = get_resource_type_from_instance(instance) return self._resource_name From 7c589be5efe203d9f1c6feb5e68707cc07247786 Mon Sep 17 00:00:00 2001 From: Stefan Heinemann Date: Fri, 29 Apr 2016 18:29:10 +0200 Subject: [PATCH 20/56] Updated the readme for testing (#234) --- README.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 5a65a9a6..960ebad9 100644 --- a/README.rst +++ b/README.rst @@ -107,9 +107,14 @@ Browse to http://localhost:8000 Running Tests ^^^^^^^^^^^^^ +It is recommended to create a virtualenv for testing. Assuming it is already +installed and activated: + :: - $ python runtests.py + $ pip install -e . + $ pip install -r requirements-development.txt + $ py.test ----- From 9ed6fd37a305d5b1e19af3592c3ff7b9c84e9c3d Mon Sep 17 00:00:00 2001 From: Joe Esposito Date: Fri, 29 Apr 2016 12:34:26 -0400 Subject: [PATCH 21/56] Allow exception handler to be used by normal DRF views: (#233) * Add top-level 'errors' object to non-JSON-API responses * Allow configuring the exception handler to be used _only_ in JSON API views or uniformly across all views --- rest_framework_json_api/exceptions.py | 28 +++++++++++++++++++++++++-- rest_framework_json_api/renderers.py | 5 +---- rest_framework_json_api/utils.py | 7 +++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/rest_framework_json_api/exceptions.py b/rest_framework_json_api/exceptions.py index c581bda2..a4a78b74 100644 --- a/rest_framework_json_api/exceptions.py +++ b/rest_framework_json_api/exceptions.py @@ -1,7 +1,16 @@ +from django.conf import settings from django.utils.translation import ugettext_lazy as _ from rest_framework import status, exceptions from rest_framework_json_api import utils +from rest_framework_json_api import renderers + + +def rendered_with_json_api(view): + for renderer_class in getattr(view, 'renderer_classes', []): + if issubclass(renderer_class, renderers.JSONRenderer): + return True + return False def exception_handler(exc, context): @@ -12,11 +21,26 @@ def exception_handler(exc, context): # # Also see: https://github.com/django-json-api/django-rest-framework-json-api/issues/158 from rest_framework.views import exception_handler as drf_exception_handler - response = drf_exception_handler(exc, context) + # Render exception with DRF + response = drf_exception_handler(exc, context) if not response: return response - return utils.format_drf_errors(response, context, exc) + + # Use regular DRF format if not rendered by DRF JSON API and not uniform + is_json_api_view = rendered_with_json_api(context['view']) + is_uniform = getattr(settings, 'JSON_API_UNIFORM_EXCEPTIONS', False) + if not is_json_api_view and not is_uniform: + return response + + # Convert to DRF JSON API error format + response = utils.format_drf_errors(response, context, exc) + + # Add top-level 'errors' object when not rendered by DRF JSON API + if not is_json_api_view: + response.data = utils.format_errors(response.data) + + return response class Conflict(exceptions.APIException): diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 518b653e..bd3184e8 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -381,11 +381,8 @@ def render_relationship_view(self, data, accepted_media_type=None, renderer_cont ) def render_errors(self, data, accepted_media_type=None, renderer_context=None): - # Get the resource name. - if len(data) > 1 and isinstance(data, list): - data.sort(key=lambda x: x.get('source', {}).get('pointer', '')) return super(JSONRenderer, self).render( - {'errors': data}, accepted_media_type, renderer_context + utils.format_errors(data), accepted_media_type, renderer_context ) def render(self, data, accepted_media_type=None, renderer_context=None): diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 88a06ba6..261640c6 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -315,4 +315,11 @@ def format_drf_errors(response, context, exc): context['view'].resource_name = 'errors' response.data = errors + return response + + +def format_errors(data): + if len(data) > 1 and isinstance(data, list): + data.sort(key=lambda x: x.get('source', {}).get('pointer', '')) + return {'errors': data} From 2bd4aea03307bbc1b732142a610343dcf4601c5c Mon Sep 17 00:00:00 2001 From: Martin Maillard Date: Fri, 29 Apr 2016 18:36:06 +0200 Subject: [PATCH 22/56] Fix included resource type inconsistency (#229) When setting `resource_name = None`, the related instance's resource name is used in `relationships`, but `None` is used in `included`. This is related to #94 and #124 --- example/tests/integration/test_model_resource_name.py | 5 +++++ rest_framework_json_api/renderers.py | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/example/tests/integration/test_model_resource_name.py b/example/tests/integration/test_model_resource_name.py index 979b55b5..db9f7832 100644 --- a/example/tests/integration/test_model_resource_name.py +++ b/example/tests/integration/test_model_resource_name.py @@ -103,6 +103,11 @@ def test_type_match_on_included_and_inline_with_serializer_resource_name(self, c _check_relationship_and_included_comment_type_are_the_same(client, reverse("entry-list")) + def test_type_match_on_included_and_inline_without_serializer_resource_name(self, client): + serializers.CommentSerializer.Meta.resource_name = None + + _check_relationship_and_included_comment_type_are_the_same(client, reverse("entry-list")) + def test_type_match_on_included_and_inline_with_serializer_resource_name_and_JSONAPIMeta(self, client): models.Comment.__bases__ += (_PatchedModel,) serializers.CommentSerializer.Meta.resource_name = "resource_name_from_serializer" diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index bd3184e8..93285f05 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -292,9 +292,13 @@ def extract_included(fields, resource, resource_instance, included_resources): for position in range(len(serializer_data)): serializer_resource = serializer_data[position] nested_resource_instance = relation_queryset[position] + resource_type = ( + relation_type or + utils.get_resource_type_from_instance(nested_resource_instance) + ) included_data.append( JSONRenderer.build_json_resource_obj( - serializer_fields, serializer_resource, nested_resource_instance, relation_type + serializer_fields, serializer_resource, nested_resource_instance, resource_type ) ) included_data.extend( From c3e2d3967d02ddf4aed870f1ef0c9dfe2844298c Mon Sep 17 00:00:00 2001 From: jerel Date: Fri, 29 Apr 2016 12:30:49 -0500 Subject: [PATCH 23/56] Fixes #230. Keep write only fields from having an attribute key --- rest_framework_json_api/renderers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 93285f05..0f33b69c 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -43,6 +43,9 @@ def extract_attributes(fields, resource): # ID is always provided in the root of JSON API so remove it from attributes if field_name == 'id': continue + # don't output a key for write only fields + if fields[field_name].write_only: + continue # Skip fields with relations if isinstance(field, (relations.RelatedField, relations.ManyRelatedField, BaseSerializer)): continue From 2928bc49afc620d93ade61cab28aa02e1e15a9b6 Mon Sep 17 00:00:00 2001 From: jerel Date: Fri, 29 Apr 2016 12:42:54 -0500 Subject: [PATCH 24/56] Release v2.0.0 --- CHANGELOG.md | 3 +++ README.rst | 2 +- rest_framework_json_api/__init__.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 885a1b47..096fd7ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ v2.0.0 +* Fixed bug where write_only fields still had their keys rendered +* Exception handler can now easily be used on DRF-JA views alongside regular DRF views +* Added `get_related_field_name` for views subclassing RelationshipView to override * Renamed `JSON_API_FORMAT_RELATION_KEYS` to `JSON_API_FORMAT_TYPES` to match what it was actually doing * Renamed `JSON_API_PLURALIZE_RELATION_TYPE` to `JSON_API_PLURALIZE_TYPES` * Documented ResourceRelatedField and RelationshipView diff --git a/README.rst b/README.rst index 960ebad9..d9e8a1d5 100644 --- a/README.rst +++ b/README.rst @@ -80,7 +80,7 @@ From PyPI :: - $ pip install djangorestframework-jsonapi==2.0.0-beta.2 + $ pip install djangorestframework-jsonapi From Source diff --git a/rest_framework_json_api/__init__.py b/rest_framework_json_api/__init__.py index a13e93bc..31f7af4a 100644 --- a/rest_framework_json_api/__init__.py +++ b/rest_framework_json_api/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- __title__ = 'djangorestframework-jsonapi' -__version__ = '2.0.0-beta.2' +__version__ = '2.0.0' __author__ = '' __license__ = 'MIT' __copyright__ = '' From 348171e1f9edb04acf17be5cca95fe5bb4b844ab Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Fri, 29 Apr 2016 13:16:34 -0500 Subject: [PATCH 25/56] Update setup.py to classify as production/stable --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 344f8b54..384207a5 100644 --- a/setup.py +++ b/setup.py @@ -76,7 +76,7 @@ def get_package_data(package): 'inflection>=0.3.0' ], classifiers=[ - 'Development Status :: 4 - Beta', + 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Framework :: Django', 'Intended Audience :: Developers', From e6f1f162222b2a7a0acfb3dad223e3aa59df6a80 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Mon, 2 May 2016 08:07:50 -0500 Subject: [PATCH 26/56] Fixed naming error on ModelSerializer relationships --- rest_framework_json_api/renderers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 0f33b69c..1c66c927 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -211,7 +211,7 @@ def extract_relationships(fields, resource, resource_instance): if isinstance(field, ModelSerializer): relation_model = field.Meta.model - relation_type = utils.format_type(relation_model.__name__) + relation_type = utils.format_resource_type(relation_model.__name__) data.update({ field_name: { From b243d1f2507ddc1aa3a2528022191ea9a37c757e Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Mon, 2 May 2016 10:50:15 -0500 Subject: [PATCH 27/56] Updated demo database --- drf_example | Bin 54272 -> 58368 bytes example/migrations/0001_initial.py | 94 +++++++++++++++++++++++++++++ example/migrations/__init__.py | 0 3 files changed, 94 insertions(+) create mode 100644 example/migrations/0001_initial.py create mode 100644 example/migrations/__init__.py diff --git a/drf_example b/drf_example index 75f45a7bd5d5010f59415ae23d38b83898165a3a..0f6bf662bdd89c9dd56012ffa936cff89e9e6bc2 100644 GIT binary patch literal 58368 zcmeHQdvF}dS)ZPs)oS(dOP2R+S=LCh&R%4#c6Rn@-{rh#>wNNA^4TZfSq8G1)sEzq z_MzKd*|OtstbBD8MMA2eidU)vgcMLf0--1psG~yN{gI@A1d{Md5eOkbLJ?ATNiGzj zD8BCL*?H_pwv^OeWc7O8n*RFx`uqCV-80?2Jzqa_=|Z8d%k!0LNvq4MAPEQwr)60X zgbe&o!+-NL1s9STfxpOhz20R;7<=twK1dDV&k-I4e;2=o{}aD~{~doBe-Zy3{v7`F zdcvH}5#R`H1%VT!--cokj3^Ks4MQ+E0zqF8f{wiq$VVXXcXmU#TbLE_C-BeVJRTJP zR(y~6q}YaDK`)@F@PERmgrA4x&3_)*?Gu8JW@>PEsYN1@XjUuM^=dX>DQSgrcBNc+ zenpQ)l*CvhJ{F0}k<`g(0>0s7I;keokzF7?(v()Rg>s=@(2AZC$z(F7s@*=JA0+fz ztxzcwl^YAil1d^H?eYnIBN=^FD=ioGd&(#gHK9D!=@WW?G^4H5uY*96mFtF9EabI% zrCQ5s`FvKdRx8zP35?Me^qQB|iI|#B#WEd`*`%3SB3sp;Unx}e>|CW>*UR<#t!2HI zCGdG>5s9Va%HsjZ;wdwWIJ0M^24EMpT0L8=ECAr;m7*tj@pL+oik)tUJkFVU#O!&H zjLKR`&sLV}o&|{~<0&P6#t%76nK`KT9CWDhVz#8MW{Y}xp?=+~DDk)&QPd~fAd~0J zOw1;;tXE3~TB})V$USn3CgYLhlRlp?axPMb)bXb2Tj=bl-pk#sZ`!L%`(S!~!Y)wCK_BjX|fF=7I-u|OQ! zekzHeyd&=NZY-!Iqe{G6{12f^d^v#s3isg&{C4~k;y3W`;Qzu3mf&9S^5#1}m*5Dz zIS3rwi<5}myR$~0BzI-F2a9|6;A74t5!VEt(9?-WoAkL#sRUwT?`}NaBpNy73Kelb z#$zbIsFfE;|Ay{QZl%(`T{z@o7K1*lnw;#GLvJlzJ#CBb{X<8x3Pu>%si@L>Vp!5_iz#lMEXf)C>>cnOc=Gx$&OUz05Pha<2P5!fg79W;B3 zaa-u>k^1^f61#nL?v?t2CXL>OI(ntP0h7|ap9JhDA5pqKr{yQE+*q9bn-h<(z?aKJtk zvR#w$e;4i(@W0^C98 zC-F_3!&Bmai~lNqR(w_bi1^Dmg=O3>zFWK@zC*kuJ|>Q#FQHGN-$x%n??rdeBD#W3 zi-*N_^sSxNRQ5|KggWzjQLmF}B^^*6HHdT9Vd&T-4)2xFFzO_W1B`8GpM*wG2a}~O zXV4%qNlKD;OK1Rf&_x9@?Ho8Dp)nL-Qbx0c)^)@nGsz~ozehsHP=H7`X@@DT%aKE$ zL34;7+9RPs)Md#Yq(x|Ff}{yQWKftGp#*nHs2{ZxArd{%E1^;3XCgqLW$HDkOw6S2 zr-k7h!Bl;2PHI) z+L)BB^BHs|YSBAs6}J(2i`YSlm}SB`Wxyb^92l{kmI4!TM)6aMXv)H4yUn1Of5DV+^py)2*{K2s?bhpnM)RC!`G5#|K#O6gSEKP$5&S{@--( zguf%e zmwz|{9D$vIKsycwX#eNq|D93cyp$XPF9b;c7x6m;{9y?AhaF=lvL#LN-kH)on~7G!?11aX;^N~WP;-@GO<)R3U9$hQ|qOql9^&* zPKUSD=5%|G{Q3WVt!|zfM_^kaK==RR69WEU{2lx{>;nEb{3ZMa*bDq={D<&1z;EFX z;`ifUz@Nmg!0zCm!SBW|;UCAhaUK5%eilEC&*QWBZLm8yicjD&zK(O-s_@)cj=&}m z@L_~HkJ50MhC?Lm7^I<0!vPWoj?l25hKEVm)kniaG(1Sc_J?Q)Zw|us0TTLqX}F(; zJtXw)qv2i}?jfPHn})k+*iFK=E*f^yu!Dp+K*M$#`bj9Z(a=XjNx}hyNg!ez2pHpk zRlvW3)lERbSvdkb6@eu>q%R@oP+L(>s*$i7O{P@4vj!OKTPcaiq`aWlWz#Q&JYTJp zWI8aHwQ^pr=@8Vf>m|8fkO|}9r0fYxRgasM%8dE3L8Y!by8vpby8kjsnzA1 zTDeX#q`5a$0|Dk2VZQ%wr#53=ZjJ!>0s;_3{015Szrpd~2yg^;0s?d_JPn#eMI4l0Hcmn;V@MjRQeHzDu{@^ni)R?r~K~T2`Zr=x4J(Y|o zT0Um^|8TP$_HbFTab7mR51x#~;Q~znS0SOswFCZODTCH}?qw^;MFaKvgO81&#;~h!)L{mk5n^{1Laj0q4z7o}OU`Yb zk?e8}BJ4M881%NGwFMZtJai8mOu6-KU=;>+Jl5k6&H@Z@hzz(XwAvag4r9!wV`@Ay z7nyU_tict$M}2OT*S&4D`=ALmj_fl$y-Zm4((D~xT2g9K%_&KnV?}%N0T1}r&%?oz=i<1q-&q8G98Z_fWY@vdkjnR_4l~XY)xkY`hPW_wK_0>8( zMgvw@7`du1gYRGSG>B-#b{qsSX>;W4!|Z%fTNsjSC9PP513BcCa;>mX*7MCX5P*{% zmcm|+8j=lF?9>jDZXCyJoEPhGOH5AnupiIC3T+o)USY{O9p*Y#>&YPYJesRoHc3_% za(IK+F%FIJL&h@g6>FV|Dx-n5=2Oc$)|xz7`aRa0JQ~6wazyw z+7OP|S25kKw7HJ$P8e{);!bYL8DO}R2?P`yx>DWVZwVg3BLiC57{fCA&vNhkB*|onANbX=G3&5Hd%|l*J-FL zwJBw5HRGk<|ufj1~cB}X@-kG3qM5U)MQ+YZ*iBmX~z(hx&);z!jBM>gZ`kZqP4XBv1pg{(C%|qs0YWED%G-Y z-I_40_D-h#U&4U$OcdUw&*bxZKJ0!|pScA{ z#gefI2L2%BSLjRs-V(;U{i+gC)UfEGq09NkKRElPzQkhDm=Zyr8d@c&zpzv~lJ-GK z5&kYIZ`$~CUq$Ck9088Nwnrdwuv-)bEQ|=k2>J}1@cSq5uXSE__t*)4a9{wv)NhSk z$z-NEQSEXLZkqHh4QZCOTJ2_~3da?i6MH3^a-4Qp)M|BdMr@&Mp9{lO9L8vcTDG3B_%$Qw-@v!GHjZiL9p7pJg+2NPUSX*#nV8cT^=`7UPYCY#DLH7{Y=z|d zVebY?l70}Hr+cNKt}VdAEZh?vtFEC;q%C-5e7#$lSzhv}sZ`+r^sLfC+P@}`(}R2O zRvdUWWm+Wmc_Y^pcx&LxRr0r7=)eQPFv|PnFSfR2U(a!tl@%mJ`@e|q2;klG&JOHR zyvQ7Zw+w-|QAdKk-M0BW9MKa^65oEQq!Np#*GYj>fS#*Vmma6S0sC9!l|(oNllz3y zB5$N9QT1uPTC0>bdj5|{&i?`bzi$~3Tro$0Bk*P-;Pn41?iO$t1pKqp5op{NyWxb1 zcQy)xgYE6@uElIPJx+;*)npNWXhp?+P?>sp=+|7#iQ`?gS%;Y&oxsFzL&!tzY@mRwn> z!_S>_#g)8XlXJJ^m0F>^0F1!BQZ1a6$Mtf(TF`6b(Z?9uqi|qG38=Lb#!$KWHw@DS zcrwPvBJd^8NcfW;i>Qs~5h?sLjTbx%ubzx5aLR^~P+X^M#F{C|)C@5Qz8aWbs}m56 zc%@vt#fa+`lww4S4l^~Gl;;+dojC5*WwR_M26?zJGGEqi6)Rd^zEP+Z>NXsd795O{ zD$O#-008R$8=Vrwr_d?HJ%Def|F3n&{J~@r-8Fs&HYZrL-q^xX&6D^;-m^@H;Fe~Z zMh=esNo*0xu}8^alsOZ;$BgnmrjmD~sy}$_7vSz)ryJqF%q#@JTF~?v7Yf~SKjxvpG549`xt(j@u|8IHjH%mr<9|_-0)YT||CgWtvmL9E+sqNz zDgw^)e|Z1jDvn%^Bd{G2@aX?<@V9@qV@-0KIRcwUK*9o|{(r=7^hv=l%n0H|^q0bC z(N768_&n~xotw|olDP9WfACZYH4Hbg>`mvIUaJvr9CHPlEvLf_RcdlCX$RzqnC8pfNj2w6tlfvA=_TK zhou;kAAS-+F)SbkSoix-NRqxKoy$;N>h-|Fh zlv-E4ZPgbV;aRI8ZtW_bX$wvc->V)9@V-{F5+IUlsHgqG;bF8k=4f}2WL6biCRtIP zE^=Vw4(uQ}KIFM`!`8y&%$1polhcsL)Wq}**)ssUtE`6UdhaJ+f%nwl4LP&jI^Mf5 zUl`-_|E)C=F2xbpz6e<3e`EjOi-PzHdU5-fXM0<|c1rY3z39u7V)M6dtE+R`^EZ;| z)up-B=u)~=u9wROOe^I~$)~oGwl+ zUWv>u77N$To-bWHdr6s!PN>t1%gM=N`g;EA<;qp{+1uByo}bswJ#kw*GntrNT#8Jc zn*!OTThlX>tJ7zT#pxNy@7%M6soP7d(~GmWt}RZ+rf25j*A}Ns(`WOA+1pcv3un&H z&t82tqCJsT=AzHux*9!yeKuMz=1P|e7YpZ?w9*qR*P^MF*=Twt|K$1Q*+QJ^zfdyy zF5kYeq}%{KwM(TZ7PaWJE7#6U)>`a*j^sDFI$4f9YQD*$BxKlb3_dTSv2Z%3L}TjO zDMZmLuPo$sbv0gAbE$Ii#{5#Oq*W8qh16|rQN6wp<>JQDkHrny z2VFyP)FJ$n@T%~u!V4gBKc6E9eF7Q`b!mBUUP4_poYBfM#AG8TKLqK+qwU~VQHKQ; zvd@b!7*Ux-<)FdAT=be8MwD_KIshE~Bke?onM^d0>rgMGjmG^ff1uFaQZ^k#1*L`d z8>~!`os}tTvJUqE>&UpDXteVYtxYC*A21D%`j~3sYsaRRMCH8(2h(VBFl{7yXb*7o zkNAipGnptM*F(FB5n~d|pC0yPQ$XWGy9^$tp~=Hk(D>nQ;2Ah35gkniqJ&0HbV2HP zvW;o6T#(vSS;P~a1~=1ZB@k|=)FM9I0o);_jcB&0gq5hbC=UlHA7(bNMOK>ujPh{1 z!N;`Q_?T)&k^R6oJc@~48xv7#asf%%#iXeJO0*?L>k!oSd zR0Ujzu}=snr&#vPb7=k6vRw z3-}N4d+=KTf7To{^1C06@iD3!T>m=bT&u1^yPQkIGX+Z|M0NE*Bsq8 z`I;kJN|A@?kh{|u)i#-o5iN}l4Fbo=SO?SSp6b!~kZkZUZA~7gi^dNR0MEd&4x*{a zK=jba=n+UAO9q%0VqW$P0gUg|ra5>ceKXC$=_y7O^ delta 3572 zcmai1Yj6|S6~1@R>TQ8-*h^aP6MTz)211wX$P1|>BNB;r+?Z!Fr-b|!}N~`RNlfa)j9a9z3V!iorxe62<84MtoJ*atkyrN%7Ds0~+=ITcBYU zSY)*x*XvtvM&ofY5(=%;;bFaW3p6CkiTFAmf2WtmZ-`k8#-fQtBrbx+L3i(9X6S!& zz%0aYI1*}OD^%(2=pN1W{Xc_fEG)~B7}XIkzG7m^4BOJU$%Gg3LylSlYvbnk! z$}HeF&5c!K%?=AZ$h5b=duV4i)sr2{F%PNSBfHZUn+{s2IwrL{Jv^8h8OdaaJS9e` zGiu7wk@PV9mGDbU&|oUst2Kk?EmbuZHnpCRQZsnxL)$Ts-N~K)-eYhb>4~H$2BYyv zEH2$pU~@=3ByGzM@4B7pNk>Pm^@dULWJF?%7LLf_|Axd9o72N1*`e+MwfZUW&k%Tq z^~?|9q5Cwa{=j0>a8gPnr8sjcMWUg_NF*5vCB;}!3`_B7sAC}0lXla}xI;L^r=EEg~>@>)on!Z@T*)yz6*1$Nu#kPnG&7+Vln?7Ne76x$YeU zX`D4zV(MrmH5FVQeZ|=7-nyxC%hokmchYX~cN+A<12I%)t5KP%qLOL==A03ipKPNR zbUx?A$4)kv6zbwCfvfNjRv3SSCtCS(9(ZChnYEJ9pwAfeA(%=C(eWk|g=0_gB?b5z zQMY6UUx8XP;emlx`Y`K&RfPRrpwDxwxjirgGm5ed@|7mMIMq%|*!1@ z-(b@Vsf6as-6Sv$-Az?iVNv4$Vu^nYR+E;us`tQ3G^~nShM*62zkTa$SAYQbuDsLy7*CUIo7Vz+=q;4-`eufX$g488+lT%8xl0X2FJZlT(RGXhjvxb`uQ;{_S^8{u13g{T5Ri& z&<2Lo;l_R=9_(-As0*LXL}(*ZZlKl~`XCsO^ABpD5{^4TxD#wC*jrJ4&e7+ll_^SP zMQJlnR8$#+K!8qeM^~elI<#!IHO}}Jm6m!=6f0}K%KZLzK`(R#<`T4P$Vf`kYFV== zXq*eduw5lfNS4~^8!)OUDRaKL&LDJk(0nJJA9LgSzIxik5~#)%zEb>tUyKX7@i$|g z)HkpEWXyzX_RBEo^PqcQD{aQz=PGf>zLj`l%r*1$J|pG*d1F298IMpuo*e(mvCS21 zCs?8*?-BAIeSllX9fny&dEJ~R4F;h-K=U3PAFsml@oL(_4C-+Gc&n+e$souwo%lMg zoNS?`+9czX2NssNc2Y3-*ZB0p{W4>qu66OTo04vE7MD%5H5-JM7W!xJR^W-uimuWv#z@3WnwmHu)GYBhM zXg+|`2P(1sfIycr3T=9PaCME zySH~vQ&-MYFE#b12hzFX4arqd6)m*}u3gI0I%-nwwC_$EPkq!}v?{c{qo6CASqn;g zDNj8tpZcmlux)IHHtYBq{e`Pgp`I#wvX*d9a&N;Hx`zCUtW}f{w?Bqk&dM}``m=1a zKWoHi&o**nQG9DwreUV+#8W2&RMw8P!^YAb#u225)QFAT%`4i8}3gSacy<^w`FhU=#lSTrJ)^QHF1xE1~`;-g$@xz4M)? zp~A>rB=8=*z@EkGk<2OxEFZmpm;l9iiU9b)2s59h za%%+E*A~X$=a*`|PWD{qTVPim%&0DmY;-Wx*Jj2SFMC_eMRp71s^ba@cR`_&%0Uld zCqoY_mu)bUuMMJJ)Fz*45U4$U;H;1O_bw-nz++XeGUdf IIRIk%4^zv;Gynhq diff --git a/example/migrations/0001_initial.py b/example/migrations/0001_initial.py new file mode 100644 index 00000000..38cc0be9 --- /dev/null +++ b/example/migrations/0001_initial.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2016-05-02 08:26 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Author', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=50)), + ('email', models.EmailField(max_length=254)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='AuthorBio', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('body', models.TextField()), + ('author', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='bio', to='example.Author')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Blog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=100)), + ('tagline', models.TextField()), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('body', models.TextField()), + ('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='example.Author')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Entry', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('headline', models.CharField(max_length=255)), + ('body_text', models.TextField(null=True)), + ('pub_date', models.DateField(null=True)), + ('mod_date', models.DateField(null=True)), + ('n_comments', models.IntegerField(default=0)), + ('n_pingbacks', models.IntegerField(default=0)), + ('rating', models.IntegerField(default=0)), + ('authors', models.ManyToManyField(to='example.Author')), + ('blog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='example.Blog')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='comment', + name='entry', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='example.Entry'), + ), + ] diff --git a/example/migrations/__init__.py b/example/migrations/__init__.py new file mode 100644 index 00000000..e69de29b From 5cf3526b21efbf997069bbce4c2583941a26fa4f Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Mon, 2 May 2016 10:52:26 -0500 Subject: [PATCH 28/56] Release v2.0.1 --- rest_framework_json_api/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_json_api/__init__.py b/rest_framework_json_api/__init__.py index 31f7af4a..a690dc9b 100644 --- a/rest_framework_json_api/__init__.py +++ b/rest_framework_json_api/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- __title__ = 'djangorestframework-jsonapi' -__version__ = '2.0.0' +__version__ = '2.0.1' __author__ = '' __license__ = 'MIT' __copyright__ = '' From 7ad660b2534bed3b30c64a55a0e79f59b3db1a70 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Mon, 2 May 2016 10:58:54 -0500 Subject: [PATCH 29/56] Updated changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 096fd7ae..048c7744 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ +v2.0.1 + +* Fixed naming error that caused ModelSerializer relationships to fail + v2.0.0 * Fixed bug where write_only fields still had their keys rendered From bd9b5a5d7a54a3e2783f9bc95b3c8d9111c212d0 Mon Sep 17 00:00:00 2001 From: Scott Fisk Date: Tue, 31 May 2016 14:55:02 -0400 Subject: [PATCH 30/56] Update tox.ini (#246) Updated tox file to not pull in a django 1.10 build when testing against django 1.9 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9ee8fafb..438981dd 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ envlist = deps = django17: Django>=1.7,<1.8 django18: Django>=1.8,<1.9 - django19: Django>=1.9b1 + django19: Django>=1.9,<1.10 drf31: djangorestframework>=3.1,<3.2 drf32: djangorestframework>=3.2,<3.3 drf33: djangorestframework>=3.3,<3.4 From d3eac6dbff6fc8c8e21734bf44ded2bbd42ad34f Mon Sep 17 00:00:00 2001 From: Tony Pilara Date: Tue, 31 May 2016 13:30:33 -0700 Subject: [PATCH 31/56] Require 'id' is included in PATCH request (#245) * Require 'id' included in PATCH request * Add missing 'id' to test --- example/tests/test_model_viewsets.py | 19 +++++++++++++++++++ example/tests/test_views.py | 1 + rest_framework_json_api/parsers.py | 2 ++ 3 files changed, 22 insertions(+) diff --git a/example/tests/test_model_viewsets.py b/example/tests/test_model_viewsets.py index 895f63e4..71859e1f 100644 --- a/example/tests/test_model_viewsets.py +++ b/example/tests/test_model_viewsets.py @@ -184,6 +184,25 @@ def test_key_in_detail_result(self): assert expected_dump == content_dump + def test_patch_requires_id(self): + """ + Verify that 'id' is required to be passed in an update request. + """ + data = { + 'data': { + 'type': 'users', + 'attributes': { + 'first-name': 'DifferentName' + } + } + } + + response = self.client.patch(self.detail_url, + content_type='application/vnd.api+json', + data=dump_json(data)) + + self.assertEqual(response.status_code, 400) + def test_key_in_post(self): """ Ensure a key is in the post. diff --git a/example/tests/test_views.py b/example/tests/test_views.py index a4f4ce75..7a1a07a8 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -155,6 +155,7 @@ def test_delete_relationship_overriding_with_none(self): request_data = { 'data': { 'type': 'comments', + 'id': self.second_comment.id, 'relationships': { 'author': { 'data': None diff --git a/rest_framework_json_api/parsers.py b/rest_framework_json_api/parsers.py index 30b9ad0e..dc24a2df 100644 --- a/rest_framework_json_api/parsers.py +++ b/rest_framework_json_api/parsers.py @@ -80,6 +80,8 @@ def parse(self, stream, media_type=None, parser_context=None): resource_type=resource_name ) ) + if not data.get('id') and request.method in ('PATCH', 'PUT'): + raise ParseError("The resource identifier object must contain an 'id' member") # Construct the return data parsed_data = {'id': data.get('id')} From 54f1dcd86bd571e83988c228e6ab3e3f72093d27 Mon Sep 17 00:00:00 2001 From: Tony Pilara Date: Wed, 1 Jun 2016 06:34:28 -0700 Subject: [PATCH 32/56] Fix return stale data on PATCH to-one relationship (#247) --- example/tests/test_views.py | 2 ++ rest_framework_json_api/views.py | 1 + 2 files changed, 3 insertions(+) diff --git a/example/tests/test_views.py b/example/tests/test_views.py index 7a1a07a8..774b06a7 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -101,6 +101,7 @@ def test_patch_to_one_relationship(self): } response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() + assert response.data == request_data['data'] response = self.client.get(url) assert response.data == request_data['data'] @@ -112,6 +113,7 @@ def test_patch_to_many_relationship(self): } response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 200, response.content.decode() + assert response.data == request_data['data'] response = self.client.get(url) assert response.data == request_data['data'] diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index 4b6e631a..9d4a649d 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -99,6 +99,7 @@ def patch(self, request, *args, **kwargs): serializer.is_valid(raise_exception=True) setattr(parent_obj, self.get_related_field_name(), serializer.validated_data) parent_obj.save() + related_instance_or_manager = self.get_related_instance() # Refresh instance result_serializer = self._instantiate_serializer(related_instance_or_manager) return Response(result_serializer.data) From 9d5cbff63917f0eceb0a71bd536fb573d452868e Mon Sep 17 00:00:00 2001 From: Eric Yu Date: Tue, 7 Jun 2016 15:00:36 -0700 Subject: [PATCH 33/56] Let serializers have empty field lists (#251) Currently, `fields = ()` in a serializer doesn't work because `get_serializer_fields` returns `None` --- rest_framework_json_api/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 261640c6..1bde5ff1 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -77,7 +77,7 @@ def get_serializer_fields(serializer): fields = getattr(serializer, 'fields') meta = getattr(serializer, 'Meta', None) - if fields: + if fields is not None: meta_fields = getattr(meta, 'meta_fields', {}) for field in meta_fields: try: From b65b53953babd2483e196b8434ffe3e4db9ec4e7 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Thu, 16 Jun 2016 12:11:32 -0500 Subject: [PATCH 34/56] Added a note to docs about generating a self link. --- docs/usage.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 27caee0c..68196174 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -449,9 +449,14 @@ def get_root_meta(self, resource, many): ``` to the serializer. It must return a dict and will be merged with the existing top level `meta`. +### Links + +Adding `url` to `fields` on a serializer will add a `self` link to the `links` key. + +Related links will be created automatically when using the Relationship View. + From 09d841b4253b0acda31a00642dfccfcfa8e8595a Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Thu, 16 Jun 2016 12:17:51 -0500 Subject: [PATCH 35/56] Added self link to blog serializer example. --- example/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/serializers.py b/example/serializers.py index e259a10b..c1b1c6b4 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -17,7 +17,7 @@ def get_root_meta(self, resource, many): class Meta: model = Blog - fields = ('name', ) + fields = ('name', 'url',) meta_fields = ('copyright',) From 2994592f315e5472ed32488f6d8aa618f4f3d020 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Thu, 16 Jun 2016 12:25:34 -0500 Subject: [PATCH 36/56] Handle self link shown in test output --- example/tests/integration/test_meta.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/example/tests/integration/test_meta.py b/example/tests/integration/test_meta.py index d854a34b..ce8b4fab 100644 --- a/example/tests/integration/test_meta.py +++ b/example/tests/integration/test_meta.py @@ -16,6 +16,9 @@ def test_top_level_meta_for_list_view(blog, client): "attributes": { "name": blog.name }, + "links": { + "self": 'http://testserver/blogs/1' + }, "meta": { "copyright": datetime.now().year }, @@ -48,6 +51,9 @@ def test_top_level_meta_for_detail_view(blog, client): "attributes": { "name": blog.name }, + "links": { + "self": "http://testserver/blogs/1" + }, "meta": { "copyright": datetime.now().year }, From c033db9a46bdd3e77beecb66beee89419be7ab97 Mon Sep 17 00:00:00 2001 From: Jozef Date: Thu, 23 Jun 2016 23:44:32 +0200 Subject: [PATCH 37/56] Add option to specify default included resources (#250) * Add option to specify default included resources Let's provide an extra JSONAPIMeta configuration option that specifies resources to be listed in the 'included' section of the response. These resources shall be included even if they're not explicitly mentioned in the 'include' request parameter. * Re-trigger Travis Build script The previous build failure was caused by some random environment issue. * Ignore default 'included' resources if specified in request Conform to the specs and ensure that no other resources are included in the response other than those explicitely requested inside the 'include' parameter in request. * Add tests for default included_resources feature --- example/tests/integration/test_includes.py | 20 ++++++++++++++++---- requirements-development.txt | 1 + rest_framework_json_api/renderers.py | 13 +++++++------ rest_framework_json_api/utils.py | 7 +++++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/example/tests/integration/test_includes.py b/example/tests/integration/test_includes.py index 05c59131..8e2a7a2a 100644 --- a/example/tests/integration/test_includes.py +++ b/example/tests/integration/test_includes.py @@ -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' @@ -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' diff --git a/requirements-development.txt b/requirements-development.txt index 6aa243bd..78ccdc91 100644 --- a/requirements-development.txt +++ b/requirements-development.txt @@ -4,3 +4,4 @@ pytest-django pytest-factoryboy fake-factory tox +mock diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 1c66c927..0a11063e 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -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 @@ -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) + if serializer is not None: # Get the serializer fields diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 1bde5ff1..514bd890 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -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())) From bd4b64e304705112c8470e2bd7fe6741b56e62ac Mon Sep 17 00:00:00 2001 From: Alex Ahn Date: Thu, 23 Jun 2016 17:49:18 -0400 Subject: [PATCH 38/56] try to use field.remote_field instead of field.related (#255) --- rest_framework_json_api/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 514bd890..c532e78e 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -191,7 +191,10 @@ def get_related_resource_type(relation): # Django 1.7 relation_model = parent_model_relation.related.model elif hasattr(parent_model_relation, 'field'): - relation_model = parent_model_relation.field.related.model + try: + relation_model = parent_model_relation.field.remote_field.model + except AttributeError: + relation_model = parent_model_relation.field.related.model else: return get_related_resource_type(parent_model_relation) return get_resource_type_from_model(relation_model) From c93dea1388c18e2b1314b91b0e04fcf4168f84da Mon Sep 17 00:00:00 2001 From: Brandon Birkholz Date: Tue, 12 Jul 2016 10:19:51 -0700 Subject: [PATCH 39/56] Convert includes from camel to snake case (#257) --- rest_framework_json_api/renderers.py | 2 ++ rest_framework_json_api/serializers.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 0a11063e..83332566 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -4,6 +4,7 @@ import copy from collections import OrderedDict +import inflection from django.utils import six, encoding from rest_framework import relations from rest_framework import renderers @@ -237,6 +238,7 @@ def extract_included(fields, resource, resource_instance, included_resources): context = current_serializer.context included_serializers = utils.get_included_serializers(current_serializer) included_resources = copy.copy(included_resources) + included_resources = [inflection.underscore(value) for value in included_resources] for field_name, field in six.iteritems(fields): # Skip URL field diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index 953c4437..24a73015 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -1,3 +1,4 @@ +import inflection from django.utils.translation import ugettext_lazy as _ from rest_framework.exceptions import ParseError from rest_framework.serializers import * @@ -75,7 +76,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 = inflection.underscore(field_path[0]) this_included_serializer = serializers.get(this_field_name) if this_included_serializer is None: raise ParseError( From 184ab5fd4acfbb2ca4a0147f683da7ac717ec946 Mon Sep 17 00:00:00 2001 From: Thomas Bartelmess Date: Sun, 17 Jul 2016 13:50:38 -0400 Subject: [PATCH 40/56] add a test for including many objects from a related serializer --- example/serializers.py | 1 + example/tests/integration/test_includes.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/example/serializers.py b/example/serializers.py index c1b1c6b4..7929577b 100644 --- a/example/serializers.py +++ b/example/serializers.py @@ -35,6 +35,7 @@ def __init__(self, *args, **kwargs): 'authors': 'example.serializers.AuthorSerializer', 'comments': 'example.serializers.CommentSerializer', 'featured': 'example.serializers.EntrySerializer', + 'suggested': 'example.serializers.EntrySerializer', } body_format = serializers.SerializerMethodField() diff --git a/example/tests/integration/test_includes.py b/example/tests/integration/test_includes.py index 8e2a7a2a..556e5bf0 100644 --- a/example/tests/integration/test_includes.py +++ b/example/tests/integration/test_includes.py @@ -50,6 +50,15 @@ def test_dynamic_related_data_is_included(single_entry, entry_factory, client): assert len(included) == 1, 'The dynamically included blog entries are of an incorrect count' +def test_dynamic_many_related_data_is_included(single_entry, entry_factory, client): + entry_factory() + response = client.get(reverse("entry-detail", kwargs={'pk': single_entry.pk}) + '?include=suggested') + included = load_json(response.content).get('included') + + assert included + assert [x.get('type') for x in included] == ['entries'], 'Dynamic included types are incorrect' + + def test_missing_field_not_included(author_bio_factory, author_factory, client): # First author does not have a bio author = author_factory(bio=None) From c1049e48182e98cec7f00bae8cc3cfca37cd74f8 Mon Sep 17 00:00:00 2001 From: Thomas Bartelmess Date: Tue, 19 Jul 2016 10:14:58 -0400 Subject: [PATCH 41/56] =?UTF-8?q?use=20the=20presense=20of=20=E2=80=98chil?= =?UTF-8?q?d=5Frelation=E2=80=99=20in=20kwargs=20to=20see=20if=20it?= =?UTF-8?q?=E2=80=99s=20a=20many=20relationship?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rest_framework_json_api/renderers.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 83332566..d52d5d73 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -283,7 +283,12 @@ def extract_included(fields, resource, resource_instance, included_resources): serializer_class = included_serializers.get(field_name) if relation_instance_or_manager is None: continue - field = serializer_class(relation_instance_or_manager, context=context) + + many = field._kwargs.get('child_relation', None) is not None + + field = serializer_class(relation_instance_or_manager, + many=many, + context=context) serializer_data = field.data if isinstance(field, ListSerializer): From 3886878b97e0d276a3347b114fa4a78508815069 Mon Sep 17 00:00:00 2001 From: Michael Boreham Date: Mon, 30 May 2016 11:52:22 +1000 Subject: [PATCH 42/56] Try to fetch the pk field from instance for pk related fields. Rather than making another query to fetch the object for every result. --- rest_framework_json_api/renderers.py | 60 ++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 83332566..74371400 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -87,20 +87,18 @@ def extract_relationships(fields, resource, resource_instance): continue source = field.source - try: - relation_instance_or_manager = getattr(resource_instance, source) - except AttributeError: - # if the field is not defined on the model then we check the serializer - # and if no value is there we skip over the field completely - serializer_method = getattr(field.parent, source, None) - if serializer_method and hasattr(serializer_method, '__call__'): - relation_instance_or_manager = serializer_method(resource_instance) - else: - continue - + serializer_method = getattr(field.parent, source, None) relation_type = utils.get_related_resource_type(field) if isinstance(field, relations.HyperlinkedIdentityField): + try: + relation_instance_or_manager = getattr(resource_instance, source) + except AttributeError: + if serializer_method and hasattr(serializer_method, '__call__'): + relation_instance_or_manager = serializer_method(resource_instance) + else: + continue + # special case for HyperlinkedIdentityField relation_data = list() @@ -124,6 +122,14 @@ def extract_relationships(fields, resource, resource_instance): continue if isinstance(field, ResourceRelatedField): + try: + relation_instance_or_manager = getattr(resource_instance, source) + except AttributeError: + if serializer_method and hasattr(serializer_method, '__call__'): + relation_instance_or_manager = serializer_method(resource_instance) + else: + continue + # special case for ResourceRelatedField relation_data = { 'data': resource.get(field_name) @@ -138,8 +144,15 @@ def extract_relationships(fields, resource, resource_instance): continue if isinstance(field, (relations.PrimaryKeyRelatedField, relations.HyperlinkedRelatedField)): - relation_id = relation_instance_or_manager.pk if resource.get(field_name) else None + try: + relation = getattr(resource_instance, '%s_id' % field.source) + except AttributeError: + if serializer_method and hasattr(serializer_method, '__call__'): + relation = serializer_method(resource_instance).pk + else: + continue + relation_id = relation if resource.get(field_name) else None relation_data = { 'data': ( OrderedDict([('type', relation_type), ('id', encoding.force_text(relation_id))]) @@ -154,6 +167,13 @@ def extract_relationships(fields, resource, resource_instance): continue if isinstance(field, relations.ManyRelatedField): + try: + relation_instance_or_manager = getattr(resource_instance, source) + except AttributeError: + if serializer_method and hasattr(serializer_method, '__call__'): + relation_instance_or_manager = serializer_method(resource_instance) + else: + continue if isinstance(field.child_relation, ResourceRelatedField): # special case for ResourceRelatedField @@ -194,6 +214,14 @@ def extract_relationships(fields, resource, resource_instance): continue if isinstance(field, ListSerializer): + try: + relation_instance_or_manager = getattr(resource_instance, source) + except AttributeError: + if serializer_method and hasattr(serializer_method, '__call__'): + relation_instance_or_manager = serializer_method(resource_instance) + else: + continue + relation_data = list() serializer_data = resource.get(field_name) @@ -211,6 +239,14 @@ def extract_relationships(fields, resource, resource_instance): continue if isinstance(field, ModelSerializer): + try: + relation_instance_or_manager = getattr(resource_instance, source) + except AttributeError: + if serializer_method and hasattr(serializer_method, '__call__'): + relation_instance_or_manager = serializer_method(resource_instance) + else: + continue + relation_model = field.Meta.model relation_type = utils.format_resource_type(relation_model.__name__) From d34b797f1840a51bff115fc7a3d02bc42f4fc4cb Mon Sep 17 00:00:00 2001 From: Michael Boreham Date: Mon, 30 May 2016 15:03:12 +1000 Subject: [PATCH 43/56] Viewset wrapper that auto prefetches related fields. --- rest_framework_json_api/views.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index 9d4a649d..ad920700 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -4,7 +4,11 @@ from django.db.models import Model from django.db.models.query import QuerySet from django.db.models.manager import Manager -from rest_framework import generics +from django.db.models.fields.related_descriptors import ( + ForwardManyToOneDescriptor, + ManyToManyDescriptor, +) +from rest_framework import generics, viewsets from rest_framework.response import Response from rest_framework.exceptions import NotFound, MethodNotAllowed from rest_framework.reverse import reverse @@ -15,6 +19,24 @@ from rest_framework_json_api.utils import get_resource_type_from_instance, OrderedDict, Hyperlink +class ModelViewSet(viewsets.ModelViewSet): + def get_queryset(self, *args, **kwargs): + qs = super().get_queryset(*args, **kwargs) + include_resources_param = self.request.query_params.get('include') if self.request else None + if include_resources_param: + included_resources = include_resources_param.split(',') + else: + included_resources = list() + for included in included_resources: + if not hasattr(qs.model, included): + continue + if issubclass(getattr(qs.model, included).__class__, ForwardManyToOneDescriptor): + qs = qs.prefetch_related(included) + elif issubclass(getattr(qs.model, included).__class__, ManyToManyDescriptor): + qs = qs.prefetch_related(included) + return qs + + class RelationshipView(generics.GenericAPIView): serializer_class = ResourceIdentifierObjectSerializer self_link_view_name = None From ccd268124983e302df1621e34be1603d91113e27 Mon Sep 17 00:00:00 2001 From: Michael Boreham Date: Mon, 30 May 2016 15:10:18 +1000 Subject: [PATCH 44/56] Get included resources as util --- rest_framework_json_api/renderers.py | 8 +------- rest_framework_json_api/serializers.py | 14 ++++++-------- rest_framework_json_api/utils.py | 15 ++++++++++----- rest_framework_json_api/views.py | 13 +++++++------ 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 74371400..581d6a81 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -465,12 +465,7 @@ 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) + included_resources = utils.get_included_resources(request, serializer) if serializer is not None: @@ -508,7 +503,6 @@ def render(self, data, accepted_media_type=None, renderer_context=None): if included: json_api_included.extend(included) - # Make sure we render data in a specific order render_data = OrderedDict() diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index 24a73015..8def4fce 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -90,14 +90,12 @@ def validate_path(serializer_class, field_path, path): validate_path(this_included_serializer, new_included_field_path, path) if request and view: - include_resources_param = request.query_params.get('include') if request else None - if include_resources_param: - included_resources = include_resources_param.split(',') - for included_field_name in included_resources: - included_field_path = included_field_name.split('.') - this_serializer_class = view.get_serializer_class() - # lets validate the current path - validate_path(this_serializer_class, included_field_path, included_field_name) + included_resources = utils.get_included_resources(request) + for included_field_name in included_resources: + included_field_path = included_field_name.split('.') + this_serializer_class = view.get_serializer_class() + # lets validate the current path + validate_path(this_serializer_class, included_field_path, included_field_name) super(IncludedResourcesValidationMixin, self).__init__(*args, **kwargs) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index c532e78e..7e9edbc8 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -235,11 +235,16 @@ 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_resources(request, serializer): + """ Build a list of included resources. """ + include_resources_param = request.query_params.get('include') if request else None + if include_resources_param: + return include_resources_param.split(',') + else: + try: + return list(serializer.JSONAPIMeta.included_resources) + except AttributeError: + return [] def get_included_serializers(serializer): diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index ad920700..74dec4ae 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -16,17 +16,18 @@ from rest_framework_json_api.exceptions import Conflict from rest_framework_json_api.serializers import ResourceIdentifierObjectSerializer -from rest_framework_json_api.utils import get_resource_type_from_instance, OrderedDict, Hyperlink +from rest_framework_json_api.utils import ( + get_resource_type_from_instance, + OrderedDict, + Hyperlink, + get_included_resources, +) class ModelViewSet(viewsets.ModelViewSet): def get_queryset(self, *args, **kwargs): qs = super().get_queryset(*args, **kwargs) - include_resources_param = self.request.query_params.get('include') if self.request else None - if include_resources_param: - included_resources = include_resources_param.split(',') - else: - included_resources = list() + included_resources = get_included_resources(self.request) for included in included_resources: if not hasattr(qs.model, included): continue From d3bb2b283b3bb3786a269f1d09b394c06d8bf304 Mon Sep 17 00:00:00 2001 From: Michael Boreham Date: Mon, 30 May 2016 16:13:40 +1000 Subject: [PATCH 45/56] Now works with nested relationship prefetching. The validation here is awkward (following the relationships through the model fields), I couldn't find a better way to ensure the included args exist for a django prefetch rather than erroring out. --- rest_framework_json_api/views.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index 74dec4ae..e799615b 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -28,13 +28,30 @@ class ModelViewSet(viewsets.ModelViewSet): def get_queryset(self, *args, **kwargs): qs = super().get_queryset(*args, **kwargs) included_resources = get_included_resources(self.request) + for included in included_resources: - if not hasattr(qs.model, included): - continue - if issubclass(getattr(qs.model, included).__class__, ForwardManyToOneDescriptor): - qs = qs.prefetch_related(included) - elif issubclass(getattr(qs.model, included).__class__, ManyToManyDescriptor): - qs = qs.prefetch_related(included) + included_model = None + levels = included.split('.') + level_model = qs.model + for level in levels: + if not hasattr(level_model, level): + break + field = getattr(level_model, level) + field_class = field.__class__ + if not ( + issubclass(field_class, ForwardManyToOneDescriptor) + or issubclass(field_class, ManyToManyDescriptor) + ): + break + + if level == levels[-1]: + included_model = field + else: + level_model = field.get_queryset().model + + if included_model is not None: + qs = qs.prefetch_related(included.replace('.', '__')) + return qs From e0c6cc53875a78d0df2a44098652dd3da907e8ad Mon Sep 17 00:00:00 2001 From: Jarek Glowacki Date: Thu, 4 Aug 2016 13:02:35 +1000 Subject: [PATCH 46/56] Missing None --- rest_framework_json_api/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 7e9edbc8..af058b7a 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -235,7 +235,7 @@ def get_resource_type_from_serializer(serializer): return get_resource_type_from_model(serializer.Meta.model) -def get_included_resources(request, serializer): +def get_included_resources(request, serializer=None): """ Build a list of included resources. """ include_resources_param = request.query_params.get('include') if request else None if include_resources_param: From 5cb9e21d17033082985e4ca2ee992259f5635b5b Mon Sep 17 00:00:00 2001 From: Jarek Glowacki Date: Thu, 4 Aug 2016 13:25:35 +1000 Subject: [PATCH 47/56] Don't break old tests --- rest_framework_json_api/serializers.py | 4 ++-- rest_framework_json_api/utils.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index 8def4fce..917ae98c 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -6,7 +6,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, get_included_resources) class ResourceIdentifierObjectSerializer(BaseSerializer): @@ -90,7 +90,7 @@ def validate_path(serializer_class, field_path, path): validate_path(this_included_serializer, new_included_field_path, path) if request and view: - included_resources = utils.get_included_resources(request) + included_resources = get_included_resources(request) for included_field_name in included_resources: included_field_path = included_field_name.split('.') this_serializer_class = view.get_serializer_class() diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index af058b7a..b09f5c68 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -241,10 +241,14 @@ def get_included_resources(request, serializer=None): if include_resources_param: return include_resources_param.split(',') else: - try: - return list(serializer.JSONAPIMeta.included_resources) - except AttributeError: - return [] + return get_default_included_resources_from_serializer(serializer) + + +def get_default_included_resources_from_serializer(serializer): + try: + return list(serializer.JSONAPIMeta.included_resources) + except AttributeError: + return [] def get_included_serializers(serializer): From b2ec862863f97d5aa11973a909ebb4587be6bd8e Mon Sep 17 00:00:00 2001 From: Jarek Glowacki Date: Thu, 4 Aug 2016 14:15:21 +1000 Subject: [PATCH 48/56] Test againts dj110/drf34 --- .travis.yml | 9 +++++++++ tox.ini | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ec66ad00..9d00539e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,18 +13,27 @@ env: - TOXENV=py27-django18-drf31 - TOXENV=py27-django18-drf32 - TOXENV=py27-django18-drf33 + - TOXENV=py27-django18-drf34 - TOXENV=py33-django18-drf31 - TOXENV=py33-django18-drf32 - TOXENV=py33-django18-drf33 + - TOXENV=py33-django18-drf34 - TOXENV=py34-django18-drf31 - TOXENV=py34-django18-drf32 - TOXENV=py34-django18-drf33 + - TOXENV=py34-django18-drf34 - TOXENV=py27-django19-drf31 - TOXENV=py27-django19-drf32 - TOXENV=py27-django19-drf33 + - TOXENV=py27-django19-drf34 - TOXENV=py34-django19-drf31 - TOXENV=py34-django19-drf32 - TOXENV=py34-django19-drf33 + - TOXENV=py34-django19-drf34 - TOXENV=py35-django19-drf31 - TOXENV=py35-django19-drf32 - TOXENV=py35-django19-drf33 + - TOXENV=py35-django19-drf34 + - TOXENV=py27-django110-drf34 + - TOXENV=py34-django110-drf34 + - TOXENV=py35-django110-drf34 diff --git a/tox.ini b/tox.ini index 438981dd..0e1c4062 100644 --- a/tox.ini +++ b/tox.ini @@ -2,16 +2,19 @@ envlist = py{27,33,34}-django17-drf{31,32}, py{27,33,34}-django18-drf{31,32,33}, - py{27,34,35}-django19-drf{31,32,33}, + py{27,34,35}-django19-drf{31,32,33,34}, + py{27,34,35}-django110-drf{34}, [testenv] deps = django17: Django>=1.7,<1.8 django18: Django>=1.8,<1.9 django19: Django>=1.9,<1.10 + django110: Django>=1.10,<1.11 drf31: djangorestframework>=3.1,<3.2 drf32: djangorestframework>=3.2,<3.3 drf33: djangorestframework>=3.3,<3.4 + drf34: djangorestframework>=3.4,<3.5 -r{toxinidir}/requirements-development.txt setenv = @@ -20,4 +23,3 @@ setenv = commands = py.test --basetemp={envtmpdir} - From 04a100cb9abd0ecaf6c5dc208f1260c579386eb5 Mon Sep 17 00:00:00 2001 From: Jarek Glowacki Date: Thu, 4 Aug 2016 15:07:22 +1000 Subject: [PATCH 49/56] Pre-dj19 compat --- rest_framework_json_api/views.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index e799615b..77bf9b91 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -4,10 +4,16 @@ from django.db.models import Model from django.db.models.query import QuerySet from django.db.models.manager import Manager -from django.db.models.fields.related_descriptors import ( - ForwardManyToOneDescriptor, - ManyToManyDescriptor, -) +if django.VERSION < (1, 9): + from django.db.models.fields.related import ( + ReverseSingleRelatedObjectDescriptor as ForwardManyToOneDescriptor, + ManyRelatedObjectsDescriptor as ManyToManyDescriptor, + ) +else: + from django.db.models.fields.related_descriptors import ( + ForwardManyToOneDescriptor, + ManyToManyDescriptor, + ) from rest_framework import generics, viewsets from rest_framework.response import Response from rest_framework.exceptions import NotFound, MethodNotAllowed From 0aedffb88fc7009f95e8ca35ec65a4e594d6c685 Mon Sep 17 00:00:00 2001 From: Jozef Date: Tue, 9 Aug 2016 14:42:53 +0200 Subject: [PATCH 50/56] Support regular serializers * initial fix for regular serializer relations * fixes to resolve correct resource_name * prioritize serializer resource_name * minor fix to included serializers --- .gitignore | 3 + rest_framework_json_api/renderers.py | 72 ++++++++++++++---------- rest_framework_json_api/utils.py | 82 ++++++++++++++++------------ 3 files changed, 91 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index 3177afc7..29fb669d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ pip-delete-this-directory.txt # Pycharm project files .idea/ +# PyTest cache +.cache/ + # Tox .tox/ diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index 83332566..f3e14cd0 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -5,10 +5,11 @@ from collections import OrderedDict import inflection +from django.db.models import Manager, QuerySet from django.utils import six, encoding from rest_framework import relations from rest_framework import renderers -from rest_framework.serializers import BaseSerializer, ListSerializer, ModelSerializer +from rest_framework.serializers import BaseSerializer, Serializer, ListSerializer, ModelSerializer from rest_framework.settings import api_settings from . import utils @@ -88,16 +89,19 @@ def extract_relationships(fields, resource, resource_instance): source = field.source try: - relation_instance_or_manager = getattr(resource_instance, source) + relation_instance = getattr(resource_instance, source) except AttributeError: # if the field is not defined on the model then we check the serializer # and if no value is there we skip over the field completely serializer_method = getattr(field.parent, source, None) if serializer_method and hasattr(serializer_method, '__call__'): - relation_instance_or_manager = serializer_method(resource_instance) + relation_instance = serializer_method(resource_instance) else: continue + if isinstance(relation_instance, Manager): + relation_instance = relation_instance.all() + relation_type = utils.get_related_resource_type(field) if isinstance(field, relations.HyperlinkedIdentityField): @@ -105,8 +109,8 @@ def extract_relationships(fields, resource, resource_instance): relation_data = list() # Don't try to query an empty relation - relation_queryset = relation_instance_or_manager.all() \ - if relation_instance_or_manager is not None else list() + relation_queryset = relation_instance \ + if relation_instance is not None else list() for related_object in relation_queryset: relation_data.append( @@ -138,7 +142,7 @@ def extract_relationships(fields, resource, resource_instance): continue if isinstance(field, (relations.PrimaryKeyRelatedField, relations.HyperlinkedRelatedField)): - relation_id = relation_instance_or_manager.pk if resource.get(field_name) else None + relation_id = relation_instance.pk if resource.get(field_name) else None relation_data = { 'data': ( @@ -177,11 +181,15 @@ def extract_relationships(fields, resource, resource_instance): continue relation_data = list() - for related_object in relation_instance_or_manager.all(): - related_object_type = utils.get_instance_or_manager_resource_type(related_object) + for nested_resource_instance in relation_instance: + nested_resource_instance_type = ( + relation_type or + utils.get_resource_type_from_instance(nested_resource_instance) + ) + relation_data.append(OrderedDict([ - ('type', related_object_type), - ('id', encoding.force_text(related_object.pk)) + ('type', nested_resource_instance_type), + ('id', encoding.force_text(nested_resource_instance.pk)) ])) data.update({ field_name: { @@ -193,15 +201,19 @@ def extract_relationships(fields, resource, resource_instance): }) continue - if isinstance(field, ListSerializer): + if isinstance(field, ListSerializer) and relation_instance is not None: relation_data = list() serializer_data = resource.get(field_name) - resource_instance_queryset = list(relation_instance_or_manager.all()) + resource_instance_queryset = list(relation_instance) if isinstance(serializer_data, list): for position in range(len(serializer_data)): nested_resource_instance = resource_instance_queryset[position] - nested_resource_instance_type = utils.get_resource_type_from_instance(nested_resource_instance) + nested_resource_instance_type = ( + relation_type or + utils.get_resource_type_from_instance(nested_resource_instance) + ) + relation_data.append(OrderedDict([ ('type', nested_resource_instance_type), ('id', encoding.force_text(nested_resource_instance.pk)) @@ -210,16 +222,13 @@ def extract_relationships(fields, resource, resource_instance): data.update({field_name: {'data': relation_data}}) continue - if isinstance(field, ModelSerializer): - relation_model = field.Meta.model - relation_type = utils.format_resource_type(relation_model.__name__) - + if isinstance(field, Serializer): data.update({ field_name: { 'data': ( OrderedDict([ ('type', relation_type), - ('id', encoding.force_text(relation_instance_or_manager.pk)) + ('id', encoding.force_text(relation_instance.pk)) ]) if resource.get(field_name) else None) } }) @@ -258,16 +267,19 @@ def extract_included(fields, resource, resource_instance, included_resources): continue try: - relation_instance_or_manager = getattr(resource_instance, field_name) + relation_instance = getattr(resource_instance, field_name) except AttributeError: try: # For ManyRelatedFields if `related_name` is not set we need to access `foo_set` from `source` - relation_instance_or_manager = getattr(resource_instance, field.child_relation.source) + relation_instance = getattr(resource_instance, field.child_relation.source) except AttributeError: if not hasattr(current_serializer, field.source): continue serializer_method = getattr(current_serializer, field.source) - relation_instance_or_manager = serializer_method(resource_instance) + relation_instance = serializer_method(resource_instance) + + if isinstance(relation_instance, Manager): + relation_instance = relation_instance.all() new_included_resources = [key.replace('%s.' % field_name, '', 1) for key in included_resources @@ -275,21 +287,21 @@ def extract_included(fields, resource, resource_instance, included_resources): serializer_data = resource.get(field_name) if isinstance(field, relations.ManyRelatedField): - serializer_class = included_serializers.get(field_name) - field = serializer_class(relation_instance_or_manager.all(), many=True, context=context) + serializer_class = included_serializers[field_name] + field = serializer_class(relation_instance, many=True, context=context) serializer_data = field.data if isinstance(field, relations.RelatedField): - serializer_class = included_serializers.get(field_name) - if relation_instance_or_manager is None: + if relation_instance is None: continue - field = serializer_class(relation_instance_or_manager, context=context) + serializer_class = included_serializers[field_name] + field = serializer_class(relation_instance, context=context) serializer_data = field.data if isinstance(field, ListSerializer): serializer = field.child relation_type = utils.get_resource_type_from_serializer(serializer) - relation_queryset = list(relation_instance_or_manager.all()) + relation_queryset = list(relation_instance) # Get the serializer fields serializer_fields = utils.get_serializer_fields(serializer) @@ -312,7 +324,7 @@ def extract_included(fields, resource, resource_instance, included_resources): ) ) - if isinstance(field, ModelSerializer): + if isinstance(field, Serializer): relation_type = utils.get_resource_type_from_serializer(field) @@ -322,11 +334,11 @@ def extract_included(fields, resource, resource_instance, included_resources): included_data.append( JSONRenderer.build_json_resource_obj( serializer_fields, serializer_data, - relation_instance_or_manager, relation_type) + relation_instance, relation_type) ) included_data.extend( JSONRenderer.extract_included( - serializer_fields, serializer_data, relation_instance_or_manager, new_included_resources + serializer_fields, serializer_data, relation_instance, new_included_resources ) ) diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index c532e78e..efc0f77b 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -162,6 +162,12 @@ def format_resource_type(value, format_type=None, pluralize=None): def get_related_resource_type(relation): + try: + return get_resource_type_from_serializer(relation) + except AttributeError: + pass + + relation_model = None if hasattr(relation, '_meta'): relation_model = relation._meta.model elif hasattr(relation, 'model'): @@ -171,41 +177,39 @@ def get_related_resource_type(relation): relation_model = relation.get_queryset().model else: parent_serializer = relation.parent + parent_model = None if hasattr(parent_serializer, 'Meta'): - parent_model = parent_serializer.Meta.model - else: - parent_model = parent_serializer.parent.Meta.model - - if relation.source: - if relation.source != '*': - parent_model_relation = getattr(parent_model, relation.source) + parent_model = getattr(parent_serializer.Meta, 'model', None) + elif hasattr(parent_serializer, 'parent') and hasattr(parent_serializer.parent, 'Meta'): + parent_model = getattr(parent_serializer.parent.Meta, 'model', None) + + if parent_model is not None: + if relation.source: + if relation.source != '*': + parent_model_relation = getattr(parent_model, relation.source) + else: + parent_model_relation = getattr(parent_model, relation.field_name) else: - parent_model_relation = getattr(parent_model, relation.field_name) - else: - parent_model_relation = getattr(parent_model, parent_serializer.field_name) - - if hasattr(parent_model_relation, 'related'): - try: - relation_model = parent_model_relation.related.related_model - except AttributeError: - # Django 1.7 - relation_model = parent_model_relation.related.model - elif hasattr(parent_model_relation, 'field'): - try: - relation_model = parent_model_relation.field.remote_field.model - except AttributeError: - relation_model = parent_model_relation.field.related.model - else: - return get_related_resource_type(parent_model_relation) - return get_resource_type_from_model(relation_model) + parent_model_relation = getattr(parent_model, parent_serializer.field_name) + + if hasattr(parent_model_relation, 'related'): + try: + relation_model = parent_model_relation.related.related_model + except AttributeError: + # Django 1.7 + relation_model = parent_model_relation.related.model + elif hasattr(parent_model_relation, 'field'): + try: + relation_model = parent_model_relation.field.remote_field.model + except AttributeError: + relation_model = parent_model_relation.field.related.model + else: + return get_related_resource_type(parent_model_relation) + if relation_model is None: + raise APIException(_('Could not resolve resource type for relation %s' % relation)) -def get_instance_or_manager_resource_type(resource_instance_or_manager): - if hasattr(resource_instance_or_manager, 'model'): - return get_resource_type_from_manager(resource_instance_or_manager) - if hasattr(resource_instance_or_manager, '_meta'): - return get_resource_type_from_instance(resource_instance_or_manager) - pass + return get_resource_type_from_model(relation_model) def get_resource_type_from_model(model): @@ -221,7 +225,8 @@ def get_resource_type_from_queryset(qs): def get_resource_type_from_instance(instance): - return get_resource_type_from_model(instance._meta.model) + if hasattr(instance, '_meta'): + return get_resource_type_from_model(instance._meta.model) def get_resource_type_from_manager(manager): @@ -229,10 +234,15 @@ def get_resource_type_from_manager(manager): def get_resource_type_from_serializer(serializer): - if hasattr(serializer.Meta, 'resource_name'): - return serializer.Meta.resource_name - else: - return get_resource_type_from_model(serializer.Meta.model) + json_api_meta = getattr(serializer, 'JSONAPIMeta', None) + meta = getattr(serializer, 'Meta', None) + if hasattr(json_api_meta, 'resource_name'): + return json_api_meta.resource_name + elif hasattr(meta, 'resource_name'): + return meta.resource_name + elif hasattr(meta, 'model'): + return get_resource_type_from_model(meta.model) + raise AttributeError() def get_default_included_resources_from_serializer(serializer): From 34de34394e4da1a45121ad94ca169d469ed9e384 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Tue, 16 Aug 2016 08:41:30 -0500 Subject: [PATCH 51/56] Added TEMPLATES setting for Django 1.10 --- example/settings/dev.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/example/settings/dev.py b/example/settings/dev.py index b4b435ca..3cc1d6e1 100644 --- a/example/settings/dev.py +++ b/example/settings/dev.py @@ -26,6 +26,29 @@ 'example', ] +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + # insert your TEMPLATE_DIRS here + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this + # list if you haven't customized them: + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + STATIC_URL = '/static/' ROOT_URLCONF = 'example.urls' From f96f26fec3c3ce50899dfdb87e66dfd4b633e620 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Tue, 16 Aug 2016 08:42:33 -0500 Subject: [PATCH 52/56] Fixes #267. relations.py was not correctly overriding get_choices --- rest_framework_json_api/relations.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rest_framework_json_api/relations.py b/rest_framework_json_api/relations.py index 0e6594d5..9762bc74 100644 --- a/rest_framework_json_api/relations.py +++ b/rest_framework_json_api/relations.py @@ -152,14 +152,16 @@ def to_representation(self, value): resource_type = resource_type if resource_type else get_resource_type_from_instance(value) return OrderedDict([('type', resource_type), ('id', str(pk))]) - @property - def choices(self): + def get_choices(self, cutoff=None): queryset = self.get_queryset() if queryset is None: # Ensure that field.choices returns something sensible # even when accessed with a read-only field. return {} + if cutoff is not None: + queryset = queryset[:cutoff] + return OrderedDict([ ( json.dumps(self.to_representation(item)), From aa66a34fbead1f6dc5342c465f5a6da44775b1e5 Mon Sep 17 00:00:00 2001 From: George Marshall Date: Thu, 18 Aug 2016 08:53:24 -0700 Subject: [PATCH 53/56] Implemented py.test runner in setup.py and added code coverage * Implemented py.test runner in setup.py * Removed testing support for Django 1.7 and Python 3.2 --- .travis.yml | 71 +- example/tests/integration/test_includes.py | 7 +- runtests.py | 3132 -------------------- setup.cfg | 5 + setup.py | 34 +- tox.ini | 9 +- 6 files changed, 73 insertions(+), 3185 deletions(-) delete mode 100644 runtests.py create mode 100644 setup.cfg mode change 100644 => 100755 setup.py diff --git a/.travis.yml b/.travis.yml index 9d00539e..6359c019 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,39 +1,38 @@ +--- language: python -python: 3.5 sudo: false -install: pip install tox -script: tox +cache: pip +matrix: + exclude: + - python: "3.3" + env: DJANGO=">=1.9,<1.10" DRF=">=3.3,<3.4" + - python: "3.3" + env: DJANGO=">=1.9,<1.10" DRF=">=3.4,<3.5" + - python: "3.3" + env: DJANGO=">=1.10,<1.11" DRF=">=3.4,<3.5" +python: + - "2.7" + - "3.3" + - "3.4" + - "3.5" env: - - TOXENV=py27-django17-drf31 - - TOXENV=py27-django17-drf32 - - TOXENV=py33-django17-drf31 - - TOXENV=py33-django17-drf32 - - TOXENV=py34-django17-drf31 - - TOXENV=py34-django17-drf32 - - TOXENV=py27-django18-drf31 - - TOXENV=py27-django18-drf32 - - TOXENV=py27-django18-drf33 - - TOXENV=py27-django18-drf34 - - TOXENV=py33-django18-drf31 - - TOXENV=py33-django18-drf32 - - TOXENV=py33-django18-drf33 - - TOXENV=py33-django18-drf34 - - TOXENV=py34-django18-drf31 - - TOXENV=py34-django18-drf32 - - TOXENV=py34-django18-drf33 - - TOXENV=py34-django18-drf34 - - TOXENV=py27-django19-drf31 - - TOXENV=py27-django19-drf32 - - TOXENV=py27-django19-drf33 - - TOXENV=py27-django19-drf34 - - TOXENV=py34-django19-drf31 - - TOXENV=py34-django19-drf32 - - TOXENV=py34-django19-drf33 - - TOXENV=py34-django19-drf34 - - TOXENV=py35-django19-drf31 - - TOXENV=py35-django19-drf32 - - TOXENV=py35-django19-drf33 - - TOXENV=py35-django19-drf34 - - TOXENV=py27-django110-drf34 - - TOXENV=py34-django110-drf34 - - TOXENV=py35-django110-drf34 + - DJANGO=">=1.8,<1.9" DRF=">=3.1,<3.2" + - DJANGO=">=1.8,<1.9" DRF=">=3.2,<3.3" + - DJANGO=">=1.8,<1.9" DRF=">=3.3,<3.4" + - DJANGO=">=1.8,<1.9" DRF=">=3.4,<3.5" + + - DJANGO=">=1.9,<1.10" DRF=">=3.3,<3.4" + - DJANGO=">=1.9,<1.10" DRF=">=3.4,<3.5" + + - DJANGO=">=1.10,<1.11" DRF=">=3.4,<3.5" +before_install: + # Force an upgrade of py to avoid VersionConflict + - pip install --upgrade py + - pip install codecov +install: + - pip install Django${DJANGO} djangorestframework${DRF} + - python setup.py install +script: + - coverage run setup.py -v test +after_success: + - codecov diff --git a/example/tests/integration/test_includes.py b/example/tests/integration/test_includes.py index 8e2a7a2a..940b8128 100644 --- a/example/tests/integration/test_includes.py +++ b/example/tests/integration/test_includes.py @@ -2,10 +2,13 @@ from django.core.urlresolvers import reverse from example.tests.utils import load_json -import mock -pytestmark = pytest.mark.django_db +try: + from unittest import mock +except ImportError: + import mock +pytestmark = pytest.mark.django_db @mock.patch('rest_framework_json_api.utils.get_default_included_resources_from_serializer', new=lambda s: ['comments']) diff --git a/runtests.py b/runtests.py deleted file mode 100644 index 3c24ac1f..00000000 --- a/runtests.py +++ /dev/null @@ -1,3132 +0,0 @@ -#! /usr/bin/env python - -# Hi There! -# You may be wondering what this giant blob of binary data here is, you might -# even be worried that we're up to something nefarious (good for you for being -# paranoid!). This is a base64 encoding of a zip file, this zip file contains -# a fully functional basic pytest script. -# -# Pytest is a thing that tests packages, pytest itself is a package that some- -# one might want to install, especially if they're looking to run tests inside -# some package they want to install. Pytest has a lot of code to collect and -# execute tests, and other such sort of "tribal knowledge" that has been en- -# coded in its code base. Because of this we basically include a basic copy -# of pytest inside this blob. We do this because it let's you as a maintainer -# or application developer who wants people who don't deal with python much to -# easily run tests without installing the complete pytest package. -# -# If you're wondering how this is created: you can create it yourself if you -# have a complete pytest installation by using this command on the command- -# line: ``py.test --genscript=runtests.py``. - -sources = """ -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 -""" - -import sys -import base64 -import zlib - -class DictImporter(object): - def __init__(self, sources): - self.sources = sources - - def find_module(self, fullname, path=None): - if fullname == "argparse" and sys.version_info >= (2,7): - # we were generated with = (3, 0): - exec("def do_exec(co, loc): exec(co, loc)\n") - import pickle - sources = sources.encode("ascii") # ensure bytes - sources = pickle.loads(zlib.decompress(base64.decodebytes(sources))) - else: - import cPickle as pickle - exec("def do_exec(co, loc): exec co in loc\n") - sources = pickle.loads(zlib.decompress(base64.decodestring(sources))) - - importer = DictImporter(sources) - sys.meta_path.insert(0, importer) - - entry = "import pytest; raise SystemExit(pytest.cmdline.main())" - do_exec(entry, locals()) # noqa diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..0cd8d9d9 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[aliases] +test = pytest + +[wheel] +universal = 1 diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 384207a5..a36a2930 --- a/setup.py +++ b/setup.py @@ -1,12 +1,21 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- +from __future__ import print_function -import re import os +import re import sys from setuptools import setup +needs_mock = sys.version_info < (3, 3) +mock = ['mock'] if needs_mock else [] +needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) +pytest_runner = ['pytest-runner'] if needs_pytest else [] +needs_sphinx = {'build_sphinx', 'upload_docs'}.intersection(sys.argv) +sphinx = ['sphinx'] if needs_sphinx else [] +needs_wheel = {'bdist_wheel'}.intersection(sys.argv) +wheel = ['wheel'] if needs_wheel else [] + def read(*paths): """ @@ -58,7 +67,6 @@ def get_package_data(package): print(" git push --tags") sys.exit() - setup( name='djangorestframework-jsonapi', version=get_version('rest_framework_json_api'), @@ -70,11 +78,6 @@ def get_package_data(package): author_email='', packages=get_packages('rest_framework_json_api'), package_data=get_package_data('rest_framework_json_api'), - install_requires=[ - 'django', - 'djangorestframework>=3.1.0', - 'inflection>=0.3.0' - ], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', @@ -89,8 +92,21 @@ def get_package_data(package): 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Software Development :: Libraries :: Application Frameworks', 'Topic :: Software Development :: Libraries :: Python Modules', - ] + ], + install_requires=[ + 'inflection>=0.3.0', + 'djangorestframework>=3.1.0', + 'django', + ], + setup_requires=pytest_runner + sphinx + wheel, + tests_require=[ + 'pytest-factoryboy', + 'pytest-django', + 'pytest>=2.8', + ] + mock, + zip_safe=False, ) diff --git a/tox.ini b/tox.ini index 0e1c4062..7db9e4cc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,11 @@ [tox] envlist = - py{27,33,34}-django17-drf{31,32}, - py{27,33,34}-django18-drf{31,32,33}, - py{27,34,35}-django19-drf{31,32,33,34}, + py{27,33,34,35}-django18-drf{31,32,33,34}, + py{27,34,35}-django19-drf{33,34}, py{27,34,35}-django110-drf{34}, [testenv] deps = - django17: Django>=1.7,<1.8 django18: Django>=1.8,<1.9 django19: Django>=1.9,<1.10 django110: Django>=1.10,<1.11 @@ -15,11 +13,10 @@ deps = drf32: djangorestframework>=3.2,<3.3 drf33: djangorestframework>=3.3,<3.4 drf34: djangorestframework>=3.4,<3.5 - -r{toxinidir}/requirements-development.txt setenv = PYTHONPATH = {toxinidir} DJANGO_SETTINGS_MODULE=example.settings.test commands = - py.test --basetemp={envtmpdir} + python setup.py test {posargs} From 38c7ca23f0e2760251b639c318389475cdf76fd8 Mon Sep 17 00:00:00 2001 From: Hamed Ahmadi Date: Thu, 18 Aug 2016 08:54:14 -0700 Subject: [PATCH 54/56] Include metadata in JSONParser output (#261) * Include metadata in Parser output The JSONParser will add metadata in the request under a top level key '_meta'. * Documenting parsing metadata in request body --- docs/api.md | 11 +++++++++ docs/usage.md | 4 +++- example/tests/test_parsers.py | 38 ++++++++++++++++++++++++++++++ rest_framework_json_api/parsers.py | 9 +++++++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 example/tests/test_parsers.py diff --git a/docs/api.md b/docs/api.md index a7f8926f..86116d5c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -47,3 +47,14 @@ Calls a `get_root_meta` function on a serializer, if it exists. `build_json_resource_obj(fields, resource, resource_instance, resource_name)` Builds the resource object (type, id, attributes) and extracts relationships. + +## rest_framework_json_api.parsers.JSONParser + +Similar to `JSONRenderer`, the `JSONParser` you may override the following methods if you need +highly custom parsing control. + +#### parse_metadata + +`parse_metadata(result)` + +Returns a dictionary which will be merged into parsed data of the request. By default, it reads the `meta` content in the request body and returns it in a dictionary with a `_meta` top level key. diff --git a/docs/usage.md b/docs/usage.md index 68196174..c1c966b7 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -375,7 +375,7 @@ class LineItemViewSet(viewsets.ModelViewSet): ### RelationshipView `rest_framework_json_api.views.RelationshipView` is used to build -relationship views (see the +relationship views (see the [JSON API spec](http://jsonapi.org/format/#fetching-relationships)). The `self` link on a relationship object should point to the corresponding relationship view. @@ -449,6 +449,8 @@ def get_root_meta(self, resource, many): ``` to the serializer. It must return a dict and will be merged with the existing top level `meta`. +To access metadata in incoming requests, the `JSONParser` will add the metadata under a top level `_meta` key in the parsed data dictionary. For instance, to access meta data from a `serializer` object, you may use `serializer.initial_data.get("_meta")`. To customize the `_meta` key, see [here](api.md). + ### Links Adding `url` to `fields` on a serializer will add a `self` link to the `links` key. diff --git a/example/tests/test_parsers.py b/example/tests/test_parsers.py new file mode 100644 index 00000000..9da1f09c --- /dev/null +++ b/example/tests/test_parsers.py @@ -0,0 +1,38 @@ +import json + +from django.test import TestCase +from io import BytesIO +from rest_framework_json_api.parsers import JSONParser + + +class TestJSONParser(TestCase): + + def setUp(self): + class MockRequest(object): + + def __init__(self): + self.method = 'GET' + + request = MockRequest() + + self.parser_context = {'request': request, 'kwargs': {}, 'view': 'BlogViewSet'} + + data = { + 'data': { + 'id': 123, + 'type': 'Blog' + }, + 'meta': { + 'random_key': 'random_value' + } + } + + self.string = json.dumps(data) + + def test_parse_include_metadata(self): + parser = JSONParser() + + stream = BytesIO(self.string.encode('utf-8')) + data = parser.parse(stream, None, self.parser_context) + + self.assertEqual(data['_meta'], {'random_key': 'random_value'}) diff --git a/rest_framework_json_api/parsers.py b/rest_framework_json_api/parsers.py index dc24a2df..a0c53f05 100644 --- a/rest_framework_json_api/parsers.py +++ b/rest_framework_json_api/parsers.py @@ -46,6 +46,14 @@ def parse_relationships(data): parsed_relationships[field_name] = list(relation for relation in field_data) return parsed_relationships + @staticmethod + def parse_metadata(result): + metadata = result.get('meta') + if metadata: + return {'_meta': metadata} + else: + return {} + def parse(self, stream, media_type=None, parser_context=None): """ Parses the incoming bytestream as JSON and returns the resulting data @@ -87,6 +95,7 @@ def parse(self, stream, media_type=None, parser_context=None): parsed_data = {'id': data.get('id')} parsed_data.update(self.parse_attributes(data)) parsed_data.update(self.parse_relationships(data)) + parsed_data.update(self.parse_metadata(result)) return parsed_data else: From 5cc8acfe0817c56bf2bff4459803de03e036d34c Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Thu, 18 Aug 2016 11:50:47 -0500 Subject: [PATCH 55/56] Release v2.1.0 --- rest_framework_json_api/__init__.py | 2 +- setup.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/rest_framework_json_api/__init__.py b/rest_framework_json_api/__init__.py index a690dc9b..5ea04a77 100644 --- a/rest_framework_json_api/__init__.py +++ b/rest_framework_json_api/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- __title__ = 'djangorestframework-jsonapi' -__version__ = '2.0.1' +__version__ = '2.1.0' __author__ = '' __license__ = 'MIT' __copyright__ = '' diff --git a/setup.py b/setup.py index a36a2930..ad4805a0 100755 --- a/setup.py +++ b/setup.py @@ -89,7 +89,6 @@ def get_package_data(package): 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', From 97e1a6ce1a923421d7ee44105fa6eaf43216c714 Mon Sep 17 00:00:00 2001 From: Jerel Unruh Date: Thu, 18 Aug 2016 12:15:36 -0500 Subject: [PATCH 56/56] Updated changelog --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 048c7744..22ea77ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,18 @@ +v2.1.0 + +* Parse `meta` in JSONParser +* Added code coverage reporting and updated Django versions tested against +* Fixed Django 1.10 compatibility +* Added support for regular non-ModelSerializers +* Added performance enhancements to reduce the number of queries in related payloads +* Fixed bug where related `SerializerMethodRelatedField` fields were not included even if in `include` +* Convert `include` field names back to snake_case +* Documented built in `url` field for generating a `self` link in the `links` key +* Fixed bug that prevented `fields = ()` in a serializer from being valid +* Fixed stale data returned in PATCH to-one relation +* Raise a `ParseError` if an `id` is not included in a PATCH request + v2.0.1 * Fixed naming error that caused ModelSerializer relationships to fail