authentik.api.pagination
Pagination which includes total pages and current page
1"""Pagination which includes total pages and current page""" 2 3from typing import TYPE_CHECKING 4 5from drf_spectacular.plumbing import build_object_type 6from rest_framework import pagination 7from rest_framework.response import Response 8 9from authentik.api.search.ql import QLSearch 10from authentik.api.v3.schema.pagination import PAGINATION 11from authentik.api.v3.schema.search import AUTOCOMPLETE_SCHEMA 12 13if TYPE_CHECKING: 14 from django.db.models import QuerySet 15 from rest_framework.request import Request 16 17 18class Pagination(pagination.PageNumberPagination): 19 """Pagination which includes total pages and current page""" 20 21 page_query_param = "page" 22 page_size_query_param = "page_size" 23 24 def get_page_size(self, request: Request) -> int: 25 if self.page_size_query_param in request.query_params: 26 page_size = super().get_page_size(request) 27 if page_size is not None: 28 return min(super().get_page_size(request), request.tenant.pagination_max_page_size) 29 return request.tenant.pagination_default_page_size 30 31 def get_paginated_response(self, data) -> Response: 32 previous_page_number = 0 33 if self.page.has_previous(): 34 previous_page_number = self.page.previous_page_number() 35 next_page_number = 0 36 if self.page.has_next(): 37 next_page_number = self.page.next_page_number() 38 return Response( 39 { 40 "pagination": { 41 "next": next_page_number, 42 "previous": previous_page_number, 43 "count": self.page.paginator.count, 44 "current": self.page.number, 45 "total_pages": self.page.paginator.num_pages, 46 "start_index": self.page.start_index(), 47 "end_index": self.page.end_index(), 48 }, 49 "results": data, 50 "autocomplete": self.get_autocomplete(), 51 } 52 ) 53 54 def paginate_queryset(self, queryset: QuerySet, request: Request, view=None): 55 self.view = view 56 return super().paginate_queryset(queryset, request, view) 57 58 def get_autocomplete(self): 59 schema = QLSearch().get_schema(self.request, self.view) 60 introspections = {} 61 if hasattr(self.view, "get_ql_fields"): 62 from authentik.api.search.schema import AKQLSchemaSerializer 63 64 introspections = AKQLSchemaSerializer().serialize( 65 schema(self.page.paginator.object_list.model) 66 ) 67 return introspections 68 69 def get_paginated_response_schema(self, schema): 70 return build_object_type( 71 properties={ 72 "pagination": PAGINATION.ref, 73 "results": schema, 74 "autocomplete": AUTOCOMPLETE_SCHEMA.ref, 75 }, 76 required=["pagination", "results", "autocomplete"], 77 ) 78 79 80class SmallerPagination(Pagination): 81 """Smaller pagination for objects which might require a lot of queries 82 to retrieve all data for.""" 83 84 max_page_size = 10
class
Pagination(rest_framework.pagination.PageNumberPagination):
19class Pagination(pagination.PageNumberPagination): 20 """Pagination which includes total pages and current page""" 21 22 page_query_param = "page" 23 page_size_query_param = "page_size" 24 25 def get_page_size(self, request: Request) -> int: 26 if self.page_size_query_param in request.query_params: 27 page_size = super().get_page_size(request) 28 if page_size is not None: 29 return min(super().get_page_size(request), request.tenant.pagination_max_page_size) 30 return request.tenant.pagination_default_page_size 31 32 def get_paginated_response(self, data) -> Response: 33 previous_page_number = 0 34 if self.page.has_previous(): 35 previous_page_number = self.page.previous_page_number() 36 next_page_number = 0 37 if self.page.has_next(): 38 next_page_number = self.page.next_page_number() 39 return Response( 40 { 41 "pagination": { 42 "next": next_page_number, 43 "previous": previous_page_number, 44 "count": self.page.paginator.count, 45 "current": self.page.number, 46 "total_pages": self.page.paginator.num_pages, 47 "start_index": self.page.start_index(), 48 "end_index": self.page.end_index(), 49 }, 50 "results": data, 51 "autocomplete": self.get_autocomplete(), 52 } 53 ) 54 55 def paginate_queryset(self, queryset: QuerySet, request: Request, view=None): 56 self.view = view 57 return super().paginate_queryset(queryset, request, view) 58 59 def get_autocomplete(self): 60 schema = QLSearch().get_schema(self.request, self.view) 61 introspections = {} 62 if hasattr(self.view, "get_ql_fields"): 63 from authentik.api.search.schema import AKQLSchemaSerializer 64 65 introspections = AKQLSchemaSerializer().serialize( 66 schema(self.page.paginator.object_list.model) 67 ) 68 return introspections 69 70 def get_paginated_response_schema(self, schema): 71 return build_object_type( 72 properties={ 73 "pagination": PAGINATION.ref, 74 "results": schema, 75 "autocomplete": AUTOCOMPLETE_SCHEMA.ref, 76 }, 77 required=["pagination", "results", "autocomplete"], 78 )
Pagination which includes total pages and current page
def
get_page_size(unknown):
25 def get_page_size(self, request: Request) -> int: 26 if self.page_size_query_param in request.query_params: 27 page_size = super().get_page_size(request) 28 if page_size is not None: 29 return min(super().get_page_size(request), request.tenant.pagination_max_page_size) 30 return request.tenant.pagination_default_page_size
def
get_paginated_response(self, data) -> rest_framework.response.Response:
32 def get_paginated_response(self, data) -> Response: 33 previous_page_number = 0 34 if self.page.has_previous(): 35 previous_page_number = self.page.previous_page_number() 36 next_page_number = 0 37 if self.page.has_next(): 38 next_page_number = self.page.next_page_number() 39 return Response( 40 { 41 "pagination": { 42 "next": next_page_number, 43 "previous": previous_page_number, 44 "count": self.page.paginator.count, 45 "current": self.page.number, 46 "total_pages": self.page.paginator.num_pages, 47 "start_index": self.page.start_index(), 48 "end_index": self.page.end_index(), 49 }, 50 "results": data, 51 "autocomplete": self.get_autocomplete(), 52 } 53 )
def
paginate_queryset(unknown):
55 def paginate_queryset(self, queryset: QuerySet, request: Request, view=None): 56 self.view = view 57 return super().paginate_queryset(queryset, request, view)
Paginate a queryset if required, either returning a
page object, or None if pagination is not configured for this view.
def
get_autocomplete(self):
59 def get_autocomplete(self): 60 schema = QLSearch().get_schema(self.request, self.view) 61 introspections = {} 62 if hasattr(self.view, "get_ql_fields"): 63 from authentik.api.search.schema import AKQLSchemaSerializer 64 65 introspections = AKQLSchemaSerializer().serialize( 66 schema(self.page.paginator.object_list.model) 67 ) 68 return introspections
81class SmallerPagination(Pagination): 82 """Smaller pagination for objects which might require a lot of queries 83 to retrieve all data for.""" 84 85 max_page_size = 10
Smaller pagination for objects which might require a lot of queries to retrieve all data for.