mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-25 08:46:10 -06:00
Remove TwoModePagination; override paginator() on NetBoxModelViewSet to determine paginator class
This commit is contained in:
parent
fd1c8aa44a
commit
a254398cec
@ -1,11 +1,13 @@
|
|||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.utils.encoding import force_str
|
from rest_framework.pagination import LimitOffsetPagination, CursorPagination, _reverse_ordering
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from rest_framework.pagination import LimitOffsetPagination, CursorPagination, BasePagination, _reverse_ordering
|
|
||||||
from rest_framework.response import Response
|
|
||||||
|
|
||||||
from netbox.config import get_config
|
from netbox.config import get_config
|
||||||
from rest_framework.compat import coreapi, coreschema
|
|
||||||
|
__all__ = (
|
||||||
|
'CursorPaginationWithNoLimit',
|
||||||
|
'OptionalLimitOffsetPagination',
|
||||||
|
'PAGINATORS',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
class OptionalLimitOffsetPagination(LimitOffsetPagination):
|
||||||
@ -183,58 +185,7 @@ class CursorPaginationWithNoLimit(CursorPagination):
|
|||||||
return self.default_page_size
|
return self.default_page_size
|
||||||
|
|
||||||
|
|
||||||
class TwoModePagination(BasePagination):
|
PAGINATORS = {
|
||||||
"""
|
'limit_offset': OptionalLimitOffsetPagination, # Default per settings.DEFAULT_PAGINATION_CLASS
|
||||||
Pagination that allows user to toggle between LimitOffsetPagination and CursorPagination. The default
|
'cursor': CursorPaginationWithNoLimit,
|
||||||
is LimitOffsetPagination.
|
}
|
||||||
"""
|
|
||||||
pagination_mode_param = 'pagination_mode'
|
|
||||||
pagination_mode_description = _(
|
|
||||||
'Mode selector for LimitOffsetPagination (default) and CursorPagination.\n'
|
|
||||||
'`offset` and `limit` are used for LimitOffsetPagination.\n'
|
|
||||||
'`cursor` and `limit` are used for CursorPagination.')
|
|
||||||
limit_offset_key = 'limit_offset'
|
|
||||||
cursor_pagination_key = 'cursor'
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
limit_offset_paginator=OptionalLimitOffsetPagination,
|
|
||||||
cursor_paginator=CursorPaginationWithNoLimit,
|
|
||||||
) -> None:
|
|
||||||
self._limit_offset_pagination = limit_offset_paginator()
|
|
||||||
self._cursor_pagination = cursor_paginator()
|
|
||||||
|
|
||||||
self._chosen_pagination = self._limit_offset_pagination
|
|
||||||
|
|
||||||
def paginate_queryset(self, queryset, request: Response, view=None):
|
|
||||||
mode = request.query_params.get(self.pagination_mode_param)
|
|
||||||
if mode == self.cursor_pagination_key:
|
|
||||||
self._chosen_pagination = self._cursor_pagination
|
|
||||||
return self._chosen_pagination.paginate_queryset(queryset, request, view)
|
|
||||||
|
|
||||||
def get_paginated_response(self, data):
|
|
||||||
return self._chosen_pagination.get_paginated_response(data)
|
|
||||||
|
|
||||||
def get_paginated_response_schema(self, schema):
|
|
||||||
return self._chosen_pagination.get_paginated_response_schema(schema)
|
|
||||||
|
|
||||||
def to_html(self): # pragma: no cover
|
|
||||||
return self._chosen_pagination.to_html()
|
|
||||||
|
|
||||||
def get_schema_fields(self, view):
|
|
||||||
mode_field = coreapi.Field(
|
|
||||||
name=self.pagination_mode_param,
|
|
||||||
required=False,
|
|
||||||
location='query',
|
|
||||||
schema=coreschema.Enum(
|
|
||||||
title='Pagination Mode',
|
|
||||||
description=force_str(self.pagination_mode_description),
|
|
||||||
enum=[self.limit_offset_key, self.cursor_pagination_key],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return [mode_field] \
|
|
||||||
+ self._limit_offset_pagination.get_schema_fields(view) \
|
|
||||||
+ self._cursor_pagination.get_schema_fields(view)[:1] # "limit" is shared between the two modes
|
|
||||||
|
|
||||||
def get_schema_operation_parameters(self, view):
|
|
||||||
return self._chosen_pagination.get_schema_operation_parameters(view)
|
|
||||||
|
@ -10,6 +10,7 @@ from rest_framework.viewsets import ModelViewSet
|
|||||||
|
|
||||||
from extras.models import ExportTemplate
|
from extras.models import ExportTemplate
|
||||||
from netbox.api.exceptions import SerializerNotFound
|
from netbox.api.exceptions import SerializerNotFound
|
||||||
|
from netbox.api.pagination import PAGINATORS
|
||||||
from netbox.constants import NESTED_SERIALIZER_PREFIX
|
from netbox.constants import NESTED_SERIALIZER_PREFIX
|
||||||
from utilities.api import get_serializer_for_model
|
from utilities.api import get_serializer_for_model
|
||||||
from utilities.exceptions import AbortRequest
|
from utilities.exceptions import AbortRequest
|
||||||
@ -93,6 +94,20 @@ class NetBoxModelViewSet(BulkUpdateModelMixin, BulkDestroyModelMixin, ObjectVali
|
|||||||
|
|
||||||
return super().get_queryset()
|
return super().get_queryset()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def paginator(self):
|
||||||
|
"""
|
||||||
|
Allow the request to designate the paginator class per the pagination_mode parameter.
|
||||||
|
"""
|
||||||
|
if not hasattr(self, '_paginator'):
|
||||||
|
if self.pagination_class is None:
|
||||||
|
self._paginator = None
|
||||||
|
elif mode := self.request.query_params.get('pagination_mode'):
|
||||||
|
self._paginator = PAGINATORS.get(mode, self.pagination_class)()
|
||||||
|
else:
|
||||||
|
self._paginator = self.pagination_class()
|
||||||
|
return self._paginator
|
||||||
|
|
||||||
def initialize_request(self, request, *args, **kwargs):
|
def initialize_request(self, request, *args, **kwargs):
|
||||||
# Check if brief=True has been passed
|
# Check if brief=True has been passed
|
||||||
if request.method == 'GET' and request.GET.get('brief'):
|
if request.method == 'GET' and request.GET.get('brief'):
|
||||||
|
@ -530,7 +530,7 @@ REST_FRAMEWORK = {
|
|||||||
'rest_framework.filters.OrderingFilter',
|
'rest_framework.filters.OrderingFilter',
|
||||||
),
|
),
|
||||||
'DEFAULT_METADATA_CLASS': 'netbox.api.metadata.BulkOperationMetadata',
|
'DEFAULT_METADATA_CLASS': 'netbox.api.metadata.BulkOperationMetadata',
|
||||||
'DEFAULT_PAGINATION_CLASS': 'netbox.api.pagination.TwoModePagination',
|
'DEFAULT_PAGINATION_CLASS': 'netbox.api.pagination.OptionalLimitOffsetPagination',
|
||||||
'DEFAULT_PARSER_CLASSES': (
|
'DEFAULT_PARSER_CLASSES': (
|
||||||
'rest_framework.parsers.JSONParser',
|
'rest_framework.parsers.JSONParser',
|
||||||
'rest_framework.parsers.MultiPartParser',
|
'rest_framework.parsers.MultiPartParser',
|
||||||
|
Loading…
Reference in New Issue
Block a user