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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Greg Aker <greg@gregaker.net>
Jamie Bliss <astronouth7303@gmail.com>
Jerel Unruh <mail@unruhdesigns.com>
Léo S. <leo@naeka.fr>
Luc Cary <luc.cary@gmail.com>
Matt Layman <https://www.mattlayman.com>
Ola Tarkowska <ola@red-aries.com>
Oliver Sauder <os@esite.ch>
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ v2.5.0 - [unreleased]
* Add new pagination classes based on JSON:API query parameter *recommendations*:
* JsonApiPageNumberPagination and JsonApiLimitOffsetPagination. See [usage docs](docs/usage.md#pagination).
* Deprecates PageNumberPagination and LimitOffsetPagination.
* Add ReadOnlyModelViewSet extension with prefetch mixins.

v2.4.0 - Released January 25, 2018

Expand Down
28 changes: 19 additions & 9 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -612,19 +612,29 @@ class QuestSerializer(serializers.ModelSerializer):

#### Performance improvements

Be aware that using included resources without any form of prefetching **WILL HURT PERFORMANCE** as it will introduce m*(n+1) queries.
Be aware that using included resources without any form of prefetching **WILL HURT PERFORMANCE** as it will introduce m\*(n+1) queries.

A viewset helper was designed to allow for greater flexibility and it is automatically available when subclassing
`views.ModelViewSet`
```
# When MyViewSet is called with ?include=author it will dynamically prefetch author and author.bio
class MyViewSet(viewsets.ModelViewSet):
`rest_framework_json_api.views.ModelViewSet`:
```python
from rest_framework_json_api import views

# When MyViewSet is called with ?include=author it will dynamically prefetch author and author.bio
class MyViewSet(views.ModelViewSet):
queryset = Book.objects.all()
prefetch_for_includes = {
'__all__': [],
'author': ['author', 'author__bio']
'category.section': ['category']
}
'__all__': [],
'author': ['author', 'author__bio'],
'category.section': ['category']
}
```

An additional convenience DJA class exists for read-only views, just as it does in DRF.
```python
from rest_framework_json_api import views

class MyReadOnlyViewSet(views.ReadOnlyModelViewSet):
# ...
```

The special keyword `__all__` can be used to specify a prefetch which should be done regardless of the include, similar to making the prefetch yourself on the QuerySet.
Expand Down
27 changes: 22 additions & 5 deletions example/tests/unit/test_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,31 @@ class DummyTestViewSet(views.ModelViewSet):
serializer_class = DummyTestSerializer


class ReadOnlyDummyTestViewSet(views.ReadOnlyModelViewSet):
queryset = Entry.objects.all()
serializer_class = DummyTestSerializer


def render_dummy_test_serialized_view(view_class):
serializer = DummyTestSerializer(instance=Entry())
renderer = JSONRenderer()
return renderer.render(
serializer.data,
renderer_context={'view': view_class()})


def test_simple_reverse_relation_included_renderer():
'''
Test renderer when a single reverse fk relation is passed.
'''
serializer = DummyTestSerializer(instance=Entry())
renderer = JSONRenderer()
rendered = renderer.render(
serializer.data,
renderer_context={'view': DummyTestViewSet()})
rendered = render_dummy_test_serialized_view(
DummyTestViewSet)

assert rendered


def test_simple_reverse_relation_included_read_only_viewset():
rendered = render_dummy_test_serialized_view(
ReadOnlyDummyTestViewSet)

assert rendered
8 changes: 7 additions & 1 deletion rest_framework_json_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class MyViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
prefetch_for_includes = {
'__all__': [],
'author': ['author', 'author__authorbio']
'author': ['author', 'author__authorbio'],
'category.section': ['category']
}
"""
Expand Down Expand Up @@ -102,6 +102,12 @@ class ModelViewSet(AutoPrefetchMixin, PrefetchForIncludesHelperMixin, viewsets.M
pass


class ReadOnlyModelViewSet(AutoPrefetchMixin,
PrefetchForIncludesHelperMixin,
viewsets.ReadOnlyModelViewSet):
pass


class RelationshipView(generics.GenericAPIView):
serializer_class = ResourceIdentifierObjectSerializer
self_link_view_name = None
Expand Down