aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Axtens <dja@axtens.net>2020-03-18 00:59:15 +1100
committerStephen Finucane <stephen@that.guru>2020-03-19 11:51:54 +0000
commit046aa155c3bf827691bab9e1df8916c969a30d54 (patch)
tree03cca9705cd81d5ee631d993954cd388b184ecce
parent98a2d051372dcedb889c4cb94ebd8ed7b399b522 (diff)
downloadpatchwork-046aa155c3bf827691bab9e1df8916c969a30d54.tar
patchwork-046aa155c3bf827691bab9e1df8916c969a30d54.tar.gz
REST: extend performance improvements to other parts of the API
We can trivially extend what we've just done to other parts of the API. I haven't done much by way of benchmark but we're seeing multiple 'x's pretty much across the board when filtering. Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Stephen Finucane <stephen@that.guru>
-rw-r--r--patchwork/api/cover.py3
-rw-r--r--patchwork/api/filters.py36
-rw-r--r--patchwork/api/series.py4
-rw-r--r--patchwork/tests/api/test_cover.py2
-rw-r--r--patchwork/tests/api/test_series.py15
5 files changed, 36 insertions, 24 deletions
diff --git a/patchwork/api/cover.py b/patchwork/api/cover.py
index 9e86d47..c0c27fe 100644
--- a/patchwork/api/cover.py
+++ b/patchwork/api/cover.py
@@ -101,7 +101,8 @@ class CoverLetterList(ListAPIView):
def get_queryset(self):
return CoverLetter.objects.all()\
- .select_related('project', 'submitter', 'series__project')\
+ .prefetch_related('series__project')\
+ .select_related('project', 'submitter', 'series')\
.defer('content', 'headers')
diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py
index a3b6f03..f7b6a6f 100644
--- a/patchwork/api/filters.py
+++ b/patchwork/api/filters.py
@@ -164,8 +164,8 @@ class TimestampMixin(BaseFilterSet):
class SeriesFilterSet(TimestampMixin, BaseFilterSet):
- submitter = PersonFilter(queryset=Person.objects.all())
- project = ProjectFilter(queryset=Project.objects.all())
+ submitter = PersonFilter(queryset=Person.objects.all(), distinct=False)
+ project = ProjectFilter(queryset=Project.objects.all(), distinct=False)
class Meta:
model = Series
@@ -174,12 +174,12 @@ class SeriesFilterSet(TimestampMixin, BaseFilterSet):
class CoverLetterFilterSet(TimestampMixin, BaseFilterSet):
- project = ProjectFilter(queryset=Project.objects.all())
+ project = ProjectFilter(queryset=Project.objects.all(), distinct=False)
# NOTE(stephenfin): We disable the select-based HTML widgets for these
# filters as the resulting query is _huge_
series = BaseFilter(queryset=Project.objects.all(),
- widget=MultipleHiddenInput)
- submitter = PersonFilter(queryset=Person.objects.all())
+ widget=MultipleHiddenInput, distinct=False)
+ submitter = PersonFilter(queryset=Person.objects.all(), distinct=False)
class Meta:
model = CoverLetter
@@ -193,10 +193,10 @@ class PatchFilterSet(TimestampMixin, BaseFilterSet):
# NOTE(stephenfin): We disable the select-based HTML widgets for these
# filters as the resulting query is _huge_
series = BaseFilter(queryset=Series.objects.all(),
- widget=MultipleHiddenInput)
- submitter = PersonFilter(queryset=Person.objects.all())
- delegate = UserFilter(queryset=User.objects.all())
- state = StateFilter(queryset=State.objects.all())
+ widget=MultipleHiddenInput, distinct=False)
+ submitter = PersonFilter(queryset=Person.objects.all(), distinct=False)
+ delegate = UserFilter(queryset=User.objects.all(), distinct=False)
+ state = StateFilter(queryset=State.objects.all(), distinct=False)
hash = CharFilter(lookup_expr='iexact')
class Meta:
@@ -214,7 +214,7 @@ class PatchFilterSet(TimestampMixin, BaseFilterSet):
class CheckFilterSet(TimestampMixin, BaseFilterSet):
- user = UserFilter(queryset=User.objects.all())
+ user = UserFilter(queryset=User.objects.all(), distinct=False)
class Meta:
model = Check
@@ -227,13 +227,17 @@ class EventFilterSet(TimestampMixin, BaseFilterSet):
# filters as the resulting query is _huge_
# TODO(stephenfin): We should really use an AJAX widget of some form here
project = ProjectFilter(queryset=Project.objects.all(),
- widget=MultipleHiddenInput)
+ widget=MultipleHiddenInput,
+ distinct=False)
series = BaseFilter(queryset=Series.objects.all(),
- widget=MultipleHiddenInput)
+ widget=MultipleHiddenInput,
+ distinct=False)
patch = BaseFilter(queryset=Patch.objects.all(),
- widget=MultipleHiddenInput)
+ widget=MultipleHiddenInput,
+ distinct=False)
cover = BaseFilter(queryset=CoverLetter.objects.all(),
- widget=MultipleHiddenInput)
+ widget=MultipleHiddenInput,
+ distinct=False)
class Meta:
model = Event
@@ -245,8 +249,8 @@ class EventFilterSet(TimestampMixin, BaseFilterSet):
class BundleFilterSet(BaseFilterSet):
- project = ProjectFilter(queryset=Project.objects.all())
- owner = UserFilter(queryset=User.objects.all())
+ project = ProjectFilter(queryset=Project.objects.all(), distinct=False)
+ owner = UserFilter(queryset=User.objects.all(), distinct=False)
class Meta:
model = Bundle
diff --git a/patchwork/api/series.py b/patchwork/api/series.py
index df28f95..e4cffaa 100644
--- a/patchwork/api/series.py
+++ b/patchwork/api/series.py
@@ -56,8 +56,8 @@ class SeriesMixin(object):
def get_queryset(self):
return Series.objects.all()\
- .prefetch_related('patches__project',)\
- .select_related('submitter', 'cover_letter__project', 'project')
+ .prefetch_related('patches__project', 'cover_letter__project')\
+ .select_related('submitter', 'project')
class SeriesList(SeriesMixin, ListAPIView):
diff --git a/patchwork/tests/api/test_cover.py b/patchwork/tests/api/test_cover.py
index 16cc0cd..5eeb190 100644
--- a/patchwork/tests/api/test_cover.py
+++ b/patchwork/tests/api/test_cover.py
@@ -127,7 +127,7 @@ class TestCoverLetterAPI(utils.APITestCase):
series = create_series()
create_covers(5, series=series)
- with self.assertNumQueries(2):
+ with self.assertNumQueries(3):
self.client.get(self.api_url())
@utils.store_samples('cover-detail')
diff --git a/patchwork/tests/api/test_series.py b/patchwork/tests/api/test_series.py
index 8751871..491dd61 100644
--- a/patchwork/tests/api/test_series.py
+++ b/patchwork/tests/api/test_series.py
@@ -139,10 +139,17 @@ class TestSeriesAPI(utils.APITestCase):
self.assertNotIn('web_url', resp.data[0]['patches'][0])
def test_list_bug_335(self):
- """Ensure we retrieve the embedded cover letter project once."""
- self._create_series()
-
- with self.assertNumQueries(4):
+ """Ensure we retrieve the embedded cover letter project in O(1)."""
+ project_obj = create_project(linkname='myproject')
+ person_obj = create_person(email='test@example.com')
+ for i in range(10):
+ series_obj = create_series(
+ project=project_obj, submitter=person_obj,
+ )
+ create_cover(series=series_obj)
+ create_patch(series=series_obj)
+
+ with self.assertNumQueries(6):
self.client.get(self.api_url())
@utils.store_samples('series-detail')