api/{rest.py => rest/__init__.py} | 7 +++-- api/rest/pagination.py | 49 +++++++++++++++++++++++++++++++ patchew/settings.py | 2 +- tests/test_diff.py | 2 +- tests/test_rest.py | 28 +++++++++--------- 5 files changed, 69 insertions(+), 19 deletions(-) rename api/{rest.py => rest/__init__.py} (99%) create mode 100644 api/rest/pagination.py
The same problem as b67dbe8 ("series-list: optimize generation of
page links", 2022-02-23) is also there in the REST output. Remove the
overhead of the count query from REST API responses.
---
api/{rest.py => rest/__init__.py} | 7 +++--
api/rest/pagination.py | 49 +++++++++++++++++++++++++++++++
patchew/settings.py | 2 +-
tests/test_diff.py | 2 +-
tests/test_rest.py | 28 +++++++++---------
5 files changed, 69 insertions(+), 19 deletions(-)
rename api/{rest.py => rest/__init__.py} (99%)
create mode 100644 api/rest/pagination.py
diff --git a/api/rest.py b/api/rest/__init__.py
similarity index 99%
rename from api/rest.py
rename to api/rest/__init__.py
index 8117ddc..4a4b047 100644
--- a/api/rest.py
+++ b/api/rest/__init__.py
@@ -14,8 +14,8 @@ from django.http import Http404, HttpResponseRedirect
from django.template import loader
from mod import dispatch_module_hook
-from .models import Project, ProjectResult, Message, MessageResult, Result
-from .search import SearchEngine
+from ..models import Project, ProjectResult, Message, MessageResult, Result
+from ..search import SearchEngine
from rest_framework import (
permissions,
serializers,
@@ -34,6 +34,7 @@ from rest_framework.fields import (
EmailField,
ListField,
)
+from rest_framework.pagination import LimitOffsetPagination
from rest_framework.relations import HyperlinkedIdentityField
from rest_framework.response import Response
from rest_framework.views import APIView
@@ -699,7 +700,7 @@ class MessagesViewSet(BaseMessageViewSet):
pass
# Fake paginator response. Note that there is no Location header.
return Response(
- OrderedDict([("count", len(results)), ("results", results)]),
+ OrderedDict([("results", results)]),
status=status.HTTP_201_CREATED if results else status.HTTP_200_OK,
)
diff --git a/api/rest/pagination.py b/api/rest/pagination.py
new file mode 100644
index 0000000..844ef6b
--- /dev/null
+++ b/api/rest/pagination.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 Red Hat, Inc.
+#
+# Authors:
+# Paolo Bonzini <pbonzini@redhat.com>
+#
+# This work is licensed under the MIT License. Please see the LICENSE file or
+# http://opensource.org/licenses/MIT.
+
+from rest_framework.pagination import LimitOffsetPagination
+from rest_framework.response import Response
+
+
+# remove count from paginator
+
+# This is referred to in settings.py, putting it with the rest of api/rest.py
+# results in a circular dependency between modules.
+
+
+class PatchewPagination(LimitOffsetPagination):
+ def get_paginated_response(self, data):
+ return Response(
+ {
+ "next": self.get_next_link(),
+ "previous": self.get_previous_link(),
+ "results": data,
+ }
+ )
+
+ def paginate_queryset(self, queryset, request, view=None):
+ self.offset = self.get_offset(request)
+ self.limit = self.get_limit(request)
+
+ # Get one extra element to check if there is a "next" page
+ q = list(queryset[self.offset : self.offset + self.limit + 1])
+ self.count = self.offset + len(q) if len(q) else self.offset - 1
+ q.pop()
+
+ self.request = request
+ if self.count > self.limit and self.template is not None:
+ self.display_page_controls = True
+
+ return q
+
+ def get_paginated_response_schema(self, schema):
+ ret = super(PatchewPagination, self).get_paginated_response_schema(schema)
+ del ret["properties"]["count"]
+ return ret
diff --git a/patchew/settings.py b/patchew/settings.py
index 8b19d19..0b8d695 100644
--- a/patchew/settings.py
+++ b/patchew/settings.py
@@ -70,7 +70,7 @@ REST_FRAMEWORK = {
"rest_framework.authentication.TokenAuthentication",
"rest_framework.authentication.SessionAuthentication",
),
- "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
+ "DEFAULT_PAGINATION_CLASS": "api.rest.pagination.PatchewPagination",
"URL_FIELD_NAME": "resource_uri",
"PAGE_SIZE": 50,
"UPLOADED_FILES_USE_URL": True,
diff --git a/tests/test_diff.py b/tests/test_diff.py
index 6d3f311..dd74ec4 100755
--- a/tests/test_diff.py
+++ b/tests/test_diff.py
@@ -37,8 +37,8 @@ class DiffTest(PatchewTestCase):
self.cli_import("0009-obsolete-by.mbox.gz")
resp = self.api_client.get(self.REST_BASE + "series/?q=quorum")
- self.assertEqual(resp.data["count"], 3)
results = sorted(resp.data["results"], key=lambda y: y["version"])
+ self.assertEqual(len(results), 3)
self.assertEqual(results[0]["version"], 1)
self.assertEqual(results[1]["version"], 2)
self.assertEqual(results[2]["version"], 3)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 9d96fa4..d7877f6 100755
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -53,7 +53,7 @@ class RestTest(PatchewTestCase):
def test_users(self):
resp = self.api_client.get(self.REST_BASE + "users/")
- self.assertEquals(resp.data["count"], 1)
+ self.assertEquals(len(resp.data["results"]), 1)
self.assertEquals(resp.data["results"][0]["resource_uri"], self.USER_BASE)
self.assertEquals(resp.data["results"][0]["username"], self.admin.username)
@@ -64,7 +64,7 @@ class RestTest(PatchewTestCase):
def test_projects(self):
resp = self.api_client.get(self.REST_BASE + "projects/")
- self.assertEquals(resp.data["count"], 3)
+ self.assertEquals(len(resp.data["results"]), 3)
self.assertEquals(resp.data["results"][0]["resource_uri"], self.PROJECT_BASE)
self.assertEquals(resp.data["results"][0]["name"], "QEMU")
self.assertEquals(
@@ -231,7 +231,7 @@ class RestTest(PatchewTestCase):
def test_project_results_list(self):
resp1 = self.api_client.get(self.PROJECT_BASE)
resp = self.api_client.get(resp1.data["results"])
- self.assertEqual(resp.data["count"], len(resp.data["results"]))
+ self.assertEqual(len(resp.data["results"]), len(resp.data["results"]))
def test_series_single(self):
resp = self.apply_and_retrieve(
@@ -371,10 +371,10 @@ class RestTest(PatchewTestCase):
)
resp = self.api_client.get(self.REST_BASE + "series/")
- self.assertEqual(resp.data["count"], 2)
+ self.assertEqual(len(resp.data["results"]), 2)
resp = self.api_client.get(self.PROJECT_BASE + "series/")
- self.assertEqual(resp.data["count"], 2)
+ self.assertEqual(len(resp.data["results"]), 2)
resp = self.api_client.get(self.REST_BASE + "projects/12345/series/")
self.assertEqual(resp.status_code, 404)
@@ -386,7 +386,7 @@ class RestTest(PatchewTestCase):
"20160628014747.20971-1-famz@redhat.com",
)
resp = self.api_client.get(resp1.data["results"])
- self.assertEqual(resp.data["count"], len(resp.data["results"]))
+ self.assertEqual(len(resp.data["results"]), len(resp.data["results"]))
def test_series_search(self):
resp1 = self.apply_and_retrieve(
@@ -401,7 +401,7 @@ class RestTest(PatchewTestCase):
)
resp = self.api_client.get(self.REST_BASE + "series/?q=quorum")
- self.assertEqual(resp.data["count"], 1)
+ self.assertEqual(len(resp.data["results"]), 1)
self.assertEqual(
resp.data["results"][0]["resource_uri"], resp2.data["resource_uri"]
)
@@ -410,7 +410,7 @@ class RestTest(PatchewTestCase):
self.assertEqual("patches" in resp.data["results"][0], False)
resp = self.api_client.get(self.REST_BASE + "series/?q=project:QEMU")
- self.assertEqual(resp.data["count"], 2)
+ self.assertEqual(len(resp.data["results"]), 2)
def cmp_result(a, expected):
self.assertEqual(a["resource_uri"], expected["resource_uri"])
@@ -579,7 +579,7 @@ class RestTest(PatchewTestCase):
self.REST_BASE + "messages/", data, content_type="application/json"
)
self.assertEqual(resp.status_code, 201)
- self.assertEqual(resp.data["count"], 2)
+ self.assertEqual(len(resp.data["results"]), 2)
resp_get = self.api_client.get(
self.PROJECT_BASE
+ "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/"
@@ -604,7 +604,7 @@ class RestTest(PatchewTestCase):
self.REST_BASE + "messages/", data, content_type="message/rfc822"
)
self.assertEqual(resp.status_code, 201)
- self.assertEqual(resp.data["count"], 2)
+ self.assertEqual(len(resp.data["results"]), 2)
resp_get = self.api_client.get(
self.PROJECT_BASE
+ "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/"
@@ -639,7 +639,7 @@ class RestTest(PatchewTestCase):
self.REST_BASE + "messages/", data, content_type="message/rfc822"
)
self.assertEqual(resp.status_code, 200)
- self.assertEqual(resp.data["count"], 0)
+ self.assertEqual(len(resp.data["results"]), 0)
resp_get = self.api_client.get(
self.PROJECT_BASE
+ "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/"
@@ -662,7 +662,7 @@ class RestTest(PatchewTestCase):
self.REST_BASE + "messages/", data, content_type="message/rfc822"
)
self.assertEqual(resp.status_code, 201)
- self.assertEqual(resp.data["count"], 1)
+ self.assertEqual(len(resp.data["results"]), 1)
resp_get = self.api_client.get(
self.PROJECT_BASE
+ "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/"
@@ -684,7 +684,7 @@ class RestTest(PatchewTestCase):
self.REST_BASE + "messages/", data, content_type="message/rfc822"
)
self.assertEqual(resp.status_code, 201)
- self.assertEqual(resp.data["count"], 2)
+ self.assertEqual(len(resp.data["results"]), 2)
resp_get = self.api_client.get(
self.PROJECT_BASE
+ "messages/20180223132311.26555-2-marcandre.lureau@redhat.com/"
@@ -754,7 +754,7 @@ class RestTest(PatchewTestCase):
message = series.data["message"]
resp = self.api_client.get(message + "replies/")
- self.assertEqual(resp.data["count"], 4)
+ self.assertEqual(len(resp.data["results"]), 4)
self.assertEqual(
resp.data["results"][0]["resource_uri"],
self.PROJECT_BASE
--
2.35.1
_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/patchew-devel
© 2016 - 2024 Red Hat, Inc.