Skip to content
Snippets Groups Projects
Commit 58354ce6 authored by Bastien Abadie's avatar Bastien Abadie
Browse files

Merge branch 'process-elts-cursor-pagination' into 'master'

Custom cursor pagination for process elements

See merge request !1043
parents 72c6ac3d ec0695e9
No related branches found
No related tags found
1 merge request!1043Custom cursor pagination for process elements
......@@ -13,7 +13,7 @@ from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.exceptions import ValidationError
from arkindex.project.mixins import CorpusACLMixin, SelectionMixin, DeprecatedMixin
from arkindex.project.mixins import CorpusACLMixin, SelectionMixin, DeprecatedMixin, CustomPaginationViewMixin
from arkindex.project.permissions import IsVerified
from arkindex.project.openapi import AutoSchema
from arkindex.documents.models import Corpus, ElementType, Element, ClassificationState
......@@ -861,7 +861,7 @@ class ImportTranskribus(CreateAPIView):
self.dataimport.start(thumbnails=True)
class ListProcessElements(ListAPIView):
class ListProcessElements(CustomPaginationViewMixin, ListAPIView):
"""
List all elements for a specific process
"""
......@@ -966,4 +966,4 @@ class ListProcessElements(ListAPIView):
if dataimport.mode not in (DataImportMode.Elements, DataImportMode.Workers):
return Element.objects.none()
return self.retrieve_elements(dataimport).order_by('id')
return self.retrieve_elements(dataimport)
This diff is collapsed.
......@@ -338,7 +338,7 @@ class TestWorkflows(FixtureAPITestCase):
response = self.client.get(reverse('api:process-elements-list', kwargs={'pk': dataimport.id}))
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(data['count'], 1)
self.assertEqual(len(data['results']), 1)
self.assertEqual(data['results'][0]['id'], str(page.id))
@override_settings(ARKINDEX_FEATURES={'selection': False})
......
......@@ -8,6 +8,7 @@ from arkindex.documents.models import Corpus, Right
from arkindex.documents.serializers.search import SearchQuerySerializer
from arkindex.project.elastic import ESQuerySet
from arkindex.project.openapi import AutoSchema, SearchAutoSchema
from arkindex.project.pagination import CustomCursorPagination
class CorpusACLMixin(object):
......@@ -158,3 +159,22 @@ class CachedViewMixin(object):
self.cache_timeout,
key_prefix=self.cache_prefix,
)(self.dispatch)
class CustomPaginationViewMixin(object):
"""
A custom cursor pagination mixin
Elements count can be retrieved with the `with_count` parameter if there is no cursor
"""
pagination_class = CustomCursorPagination
@property
def paginator(self):
if not hasattr(self, '_paginator'):
params = self.request.query_params
with_count = (
not params.get('cursor')
and params.get('with_count') not in (None, '', 'false', '0')
)
self._paginator = self.pagination_class(with_count=with_count)
return self._paginator
......@@ -26,3 +26,53 @@ class PageNumberPagination(pagination.PageNumberPagination):
'example': 123,
}
return schema
class CustomCursorPagination(pagination.CursorPagination):
"""
A custom cursor pagination class
Count attribute and ordering may be updated when instanciating the class
"""
count = None
page_size = 20
page_size_query_param = 'page_size'
max_page_size = 1000
def __init__(self, *args, **kwargs):
self.with_count = kwargs.pop('with_count', False)
self.ordering = kwargs.pop('ordering', 'id')
super().__init__(*args, **kwargs)
def paginate_queryset(self, queryset, *args, **kwargs):
if self.with_count:
self.count = queryset.count()
return super().paginate_queryset(queryset, *args, **kwargs)
def get_paginated_response(self, data):
return Response(OrderedDict([
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('count', self.count),
('results', data)
]))
def get_schema_operation_parameters(self, view):
parameters = super().get_schema_operation_parameters(view)
parameters.append({
'name': 'with_count',
'required': False,
'in': 'query',
'description': 'Count the total number of elements. Incompatible with `cursor` parameter.',
'schema': {
'type': 'boolean',
}
})
return parameters
def get_paginated_response_schema(self, schema):
schema = super().get_paginated_response_schema(schema)
schema['properties']['count'] = {
'type': 'integer',
'example': None,
}
return schema
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment