Skip to content

Commit bea4743

Browse files
authored
Merge pull request #439 from lcary/patch-1
Extend ReadOnlyModelViewSet with prefetch mixins
2 parents 409fb65 + d8d4f5d commit bea4743

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

Diff for: AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Greg Aker <[email protected]>
66
Jamie Bliss <[email protected]>
77
Jerel Unruh <[email protected]>
88
9+
910
Matt Layman <https://www.mattlayman.com>
1011
Ola Tarkowska <[email protected]>
1112
Oliver Sauder <[email protected]>

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ v2.5.0 - [unreleased]
22
* Add new pagination classes based on JSON:API query parameter *recommendations*:
33
* JsonApiPageNumberPagination and JsonApiLimitOffsetPagination. See [usage docs](docs/usage.md#pagination).
44
* Deprecates PageNumberPagination and LimitOffsetPagination.
5+
* Add ReadOnlyModelViewSet extension with prefetch mixins.
56

67
v2.4.0 - Released January 25, 2018
78

Diff for: docs/usage.md

+19-9
Original file line numberDiff line numberDiff line change
@@ -612,19 +612,29 @@ class QuestSerializer(serializers.ModelSerializer):
612612

613613
#### Performance improvements
614614

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

617617
A viewset helper was designed to allow for greater flexibility and it is automatically available when subclassing
618-
`views.ModelViewSet`
619-
```
620-
# When MyViewSet is called with ?include=author it will dynamically prefetch author and author.bio
621-
class MyViewSet(viewsets.ModelViewSet):
618+
`rest_framework_json_api.views.ModelViewSet`:
619+
```python
620+
from rest_framework_json_api import views
621+
622+
# When MyViewSet is called with ?include=author it will dynamically prefetch author and author.bio
623+
class MyViewSet(views.ModelViewSet):
622624
queryset = Book.objects.all()
623625
prefetch_for_includes = {
624-
'__all__': [],
625-
'author': ['author', 'author__bio']
626-
'category.section': ['category']
627-
}
626+
'__all__': [],
627+
'author': ['author', 'author__bio'],
628+
'category.section': ['category']
629+
}
630+
```
631+
632+
An additional convenience DJA class exists for read-only views, just as it does in DRF.
633+
```python
634+
from rest_framework_json_api import views
635+
636+
class MyReadOnlyViewSet(views.ReadOnlyModelViewSet):
637+
# ...
628638
```
629639

630640
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.

Diff for: example/tests/unit/test_renderers.py

+22-5
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,31 @@ class DummyTestViewSet(views.ModelViewSet):
3333
serializer_class = DummyTestSerializer
3434

3535

36+
class ReadOnlyDummyTestViewSet(views.ReadOnlyModelViewSet):
37+
queryset = Entry.objects.all()
38+
serializer_class = DummyTestSerializer
39+
40+
41+
def render_dummy_test_serialized_view(view_class):
42+
serializer = DummyTestSerializer(instance=Entry())
43+
renderer = JSONRenderer()
44+
return renderer.render(
45+
serializer.data,
46+
renderer_context={'view': view_class()})
47+
48+
3649
def test_simple_reverse_relation_included_renderer():
3750
'''
3851
Test renderer when a single reverse fk relation is passed.
3952
'''
40-
serializer = DummyTestSerializer(instance=Entry())
41-
renderer = JSONRenderer()
42-
rendered = renderer.render(
43-
serializer.data,
44-
renderer_context={'view': DummyTestViewSet()})
53+
rendered = render_dummy_test_serialized_view(
54+
DummyTestViewSet)
55+
56+
assert rendered
57+
58+
59+
def test_simple_reverse_relation_included_read_only_viewset():
60+
rendered = render_dummy_test_serialized_view(
61+
ReadOnlyDummyTestViewSet)
4562

4663
assert rendered

Diff for: rest_framework_json_api/views.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class MyViewSet(viewsets.ModelViewSet):
3838
queryset = Book.objects.all()
3939
prefetch_for_includes = {
4040
'__all__': [],
41-
'author': ['author', 'author__authorbio']
41+
'author': ['author', 'author__authorbio'],
4242
'category.section': ['category']
4343
}
4444
"""
@@ -102,6 +102,12 @@ class ModelViewSet(AutoPrefetchMixin, PrefetchForIncludesHelperMixin, viewsets.M
102102
pass
103103

104104

105+
class ReadOnlyModelViewSet(AutoPrefetchMixin,
106+
PrefetchForIncludesHelperMixin,
107+
viewsets.ReadOnlyModelViewSet):
108+
pass
109+
110+
105111
class RelationshipView(generics.GenericAPIView):
106112
serializer_class = ResourceIdentifierObjectSerializer
107113
self_link_view_name = None

0 commit comments

Comments
 (0)