Skip to content

Commit

Permalink
Merge pull request #2320 from onaio/add-pagination-to-projects-endpoint
Browse files Browse the repository at this point in the history
Add pagination to projects endpoint
  • Loading branch information
KipSigei committed Sep 29, 2022
2 parents abae7f0 + 220efc9 commit ab11478
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Get a paginated list of forms
Returns a list of JSON forms using page number and the number of items per page. Use the ``page`` parameter to specify page number and ``page_size`` parameter is used to set the custom page size.

- ``page`` - Integer representing the page.
- ``page_size`` - Integer representing the number of records that should be returned in a single page.
- ``page_size`` - Integer representing the number of records that should be returned in a single page. The maximum number of items that can be requested in a page via the ``page_size`` query param is 10,000

.. raw:: html

Expand Down
38 changes: 38 additions & 0 deletions docs/projects.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,44 @@ Response
}, ...
]

Get a paginated list of Projects
---------------------------------
Returns a list of projects using page number and the number of items per page. Use the ``page`` parameter to specify page number and ``page_size`` parameter is used to set the custom page size.

- ``page`` - Integer representing the page.
- ``page_size`` - Integer representing the number of records that should be returned in a single page. The maximum number of items that can be requested in a page via the ``page_size`` query param is 10,000

.. raw:: html

<pre class="prettyprint"><b>GET</b> /api/v1/projects?<code>page</code>=<code>1</code><code>page_size</code>=<code>2</code></pre>

Example
^^^^^^^^
::

curl -X GET https://api.ona.io/api/v1/projects?page=1&page_size=2

Response
^^^^^^^^^
::

[
{
"url": "https://api.ona.io/api/v1/projects/1",
"owner": "https://api.ona.io/api/v1/users/ona",
"name": "project 1",
"date_created": "2013-07-24T13:37:39Z",
"date_modified": "2013-07-24T13:37:39Z"
},
{
"url": "https://api.ona.io/api/v1/projects/4",
"owner": "https://api.ona.io/api/v1/users/ona",
"name": "project 2",
"date_created": "2013-07-24T13:59:10Z",
"date_modified": "2013-07-24T13:59:10Z"
}, ...
]

List of Projects filter by owner/organization
----------------------------------------------
.. raw:: html
Expand Down
36 changes: 36 additions & 0 deletions onadata/apps/api/tests/viewsets/test_project_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,42 @@ def test_projects_list(self):
self.assertEqual(response.data, [serializer.data])
self.assertIn("created_by", list(response.data[0]))

def test_projects_list_with_pagination(self):
view = ProjectViewSet.as_view(
{
"get": "list",
}
)
self._project_create()
# create second project
username = self.user.username
self._project_create(
{
"name": "proj one",
"owner": f"http://testserver/api/v1/users/{username}",
"public": False,
}
)
# test without pagination
request = self.factory.get("/", **self.extra)
request.user = self.user
response = view(request)
self.assertNotEqual(response.get("Cache-Control"), None)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)

# test with pagination enabled
params = {
"page": 1,
"page_size": 1
}
request = self.factory.get("/", data=params, **self.extra)
request.user = self.user
response = view(request)
self.assertNotEqual(response.get("Cache-Control"), None)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)

# pylint: disable=invalid-name
def test_project_list_returns_projects_for_active_users_only(self):
"""Test project list returns projects of active users only."""
Expand Down
13 changes: 13 additions & 0 deletions onadata/apps/api/viewsets/project_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from onadata.libs.mixins.etags_mixin import ETagsMixin
from onadata.libs.mixins.labels_mixin import LabelsMixin
from onadata.libs.mixins.profiler_mixin import ProfilerMixin
from onadata.libs.pagination import StandardPageNumberPagination
from onadata.libs.serializers.project_serializer import (
BaseProjectSerializer,
ProjectSerializer,
Expand Down Expand Up @@ -68,6 +69,7 @@ class ProjectViewSet(
extra_lookup_fields = None
permission_classes = [ProjectPermissions]
filter_backends = (AnonUserProjectFilter, ProjectOwnerFilter, TagFilter)
pagination_class = StandardPageNumberPagination

def get_serializer_class(self):
"""Return BaseProjectSerializer class when listing projects."""
Expand Down Expand Up @@ -102,6 +104,17 @@ def retrieve(self, request, *args, **kwargs):
serializer = ProjectSerializer(self.object, context={"request": request})
return Response(serializer.data)

def list(self, request, *args, **kwargs):
"""Returns a list of projects"""
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page:
serializer = self.get_serializer(page, many=True)
else:
serializer = self.get_serializer(queryset, many=True)

return Response(serializer.data)

@action(methods=["POST", "GET"], detail=True)
def forms(self, request, **kwargs):
"""Add a form to a project or list forms for the project.
Expand Down

0 comments on commit ab11478

Please sign in to comment.