Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fbb4b03

Browse files
SafaAlfulaijsliverc
andauthored
Prefetch default included resources (#900)
Co-authored-by: Oliver Sauder <os@esite.ch>
1 parent a5df955 commit fbb4b03

File tree

4 files changed

+24
-5
lines changed

4 files changed

+24
-5
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ any parts of the framework not mentioned in the documentation should generally b
2525
OrderViewSet.as_view({'get': 'retrieve_related'}),
2626
name='order-related'),
2727
```
28+
* Ensure default `included_resources` are considered when calculating prefetches.
2829

2930

3031
### Deprecated

‎example/tests/test_performance.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from django.utils import timezone
22
from rest_framework.test import APITestCase
33

4-
from example.factories import CommentFactory
4+
from example.factories import CommentFactory, EntryFactory
55
from example.models import Author, Blog, Comment, Entry
66

77

@@ -36,6 +36,7 @@ def setUp(self):
3636
)
3737
self.comment = Comment.objects.create(entry=self.first_entry)
3838
CommentFactory.create_batch(50)
39+
EntryFactory.create_batch(50)
3940

4041
def test_query_count_no_includes(self):
4142
"""We expect a simple list view to issue only two queries.
@@ -49,7 +50,7 @@ def test_query_count_no_includes(self):
4950
self.assertEqual(len(response.data["results"]), 25)
5051

5152
def test_query_count_include_author(self):
52-
"""We expect a list view with an include have three queries:
53+
"""We expect a list view with an include have five queries:
5354
5455
1. Primary resource COUNT query
5556
2. Primary resource SELECT
@@ -70,3 +71,16 @@ def test_query_select_related_entry(self):
7071
with self.assertNumQueries(2):
7172
response = self.client.get("/comments?include=writer&page[size]=25")
7273
self.assertEqual(len(response.data["results"]), 25)
74+
75+
def test_query_prefetch_uses_included_resources(self):
76+
"""We expect a list view with `included_resources` to have three queries:
77+
78+
1. Primary resource COUNT query
79+
2. Primary resource SELECT
80+
3. Comments prefetched
81+
"""
82+
with self.assertNumQueries(3):
83+
response = self.client.get(
84+
"/entries?fields[entries]=comments&page[size]=25"
85+
)
86+
self.assertEqual(len(response.data["results"]), 25)

‎rest_framework_json_api/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def validate_path(serializer_class, field_path, path):
137137
validate_path(this_included_serializer, new_included_field_path, path)
138138

139139
if request and view:
140-
included_resources = get_included_resources(request)
140+
included_resources = get_included_resources(request, self)
141141
for included_field_name in included_resources:
142142
included_field_path = included_field_name.split(".")
143143
if "related_field" in view.kwargs:

‎rest_framework_json_api/views.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ def get_prefetch_related(self, include):
6363
def get_queryset(self, *args, **kwargs):
6464
qs = super(PreloadIncludesMixin, self).get_queryset(*args, **kwargs)
6565

66-
included_resources = get_included_resources(self.request)
66+
included_resources = get_included_resources(
67+
self.request, self.get_serializer_class()
68+
)
6769
for included in included_resources + ["__all__"]:
6870

6971
select_related = self.get_select_related(included)
@@ -82,7 +84,9 @@ def get_queryset(self, *args, **kwargs):
8284
""" This mixin adds automatic prefetching for OneToOne and ManyToMany fields. """
8385
qs = super(AutoPrefetchMixin, self).get_queryset(*args, **kwargs)
8486

85-
included_resources = get_included_resources(self.request)
87+
included_resources = get_included_resources(
88+
self.request, self.get_serializer_class()
89+
)
8690

8791
for included in included_resources + ["__all__"]:
8892
# If include was not defined, trying to resolve it automatically

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /