fix: force page limit

This commit is contained in:
ibuler
2025-09-16 11:18:41 +08:00
committed by 老广
parent 3c1fd134ae
commit e156ab6ad8
11 changed files with 32 additions and 21 deletions

View File

@@ -16,7 +16,6 @@ class CategoryViewSet(ListModelMixin, JMSGenericViewSet):
'types': TypeSerializer, 'types': TypeSerializer,
} }
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
default_limit = None
def get_queryset(self): def get_queryset(self):
return AllTypes.categories() return AllTypes.categories()

View File

@@ -14,7 +14,7 @@ class FavoriteAssetViewSet(BulkModelViewSet):
serializer_class = FavoriteAssetSerializer serializer_class = FavoriteAssetSerializer
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
filterset_fields = ['asset'] filterset_fields = ['asset']
default_limit = None page_no_limit = True
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
with tmp_to_root_org(): with tmp_to_root_org():

View File

@@ -43,7 +43,7 @@ class AssetPlatformViewSet(JMSModelViewSet):
'ops_methods': 'assets.view_platform', 'ops_methods': 'assets.view_platform',
'filter_nodes_assets': 'assets.view_platform', 'filter_nodes_assets': 'assets.view_platform',
} }
default_limit = None page_no_limit = True
def get_queryset(self): def get_queryset(self):
# 因为没有走分页逻辑,所以需要这里 prefetch # 因为没有走分页逻辑,所以需要这里 prefetch

View File

@@ -5,6 +5,7 @@ from contextlib import nullcontext
from itertools import chain from itertools import chain
from typing import Callable from typing import Callable
from django.conf import settings
from django.db import models from django.db import models
from django.db.models.signals import m2m_changed from django.db.models.signals import m2m_changed
from common.utils import is_uuid from common.utils import is_uuid
@@ -103,9 +104,20 @@ class QuerySetMixin:
if not pk or is_uuid(pk) or pk.isdigit(): if not pk or is_uuid(pk) or pk.isdigit():
return super().get_object() return super().get_object()
return self.get_queryset().get(**{self.slug_field: pk}) return self.get_queryset().get(**{self.slug_field: pk})
def limit_queryset_if_no_page(self, queryset):
# 如果分页器有设置 limit则不限制
if self.paginator and self.paginator.get_limit(self.request):
return queryset
def get_queryset(self): # 如果分页器没有设置 limit则不限制
return super().get_queryset() if getattr(self, 'page_no_limit', False):
return queryset
if not settings.DEFAULT_PAGE_SIZE:
return queryset
return queryset[:settings.DEFAULT_PAGE_SIZE]
def filter_queryset(self, queryset): def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset) queryset = super().filter_queryset(queryset)
@@ -114,6 +126,7 @@ class QuerySetMixin:
if self.action == 'metadata': if self.action == 'metadata':
queryset = queryset.none() queryset = queryset.none()
queryset = self.setup_eager_loading(queryset) queryset = self.setup_eager_loading(queryset)
queryset = self.limit_queryset_if_no_page(queryset)
return queryset return queryset
def setup_eager_loading(self, queryset, is_paginated=False): def setup_eager_loading(self, queryset, is_paginated=False):

View File

@@ -692,8 +692,9 @@ class Config(dict):
'FTP_FILE_MAX_STORE': 0, 'FTP_FILE_MAX_STORE': 0,
# API 分页 # API 分页
'MAX_LIMIT_PER_PAGE': 10000, 'MAX_LIMIT_PER_PAGE': 10000, # 给导出用
'DEFAULT_PAGE_SIZE': 10, 'MAX_PAGE_SIZE': 1000,
'DEFAULT_PAGE_SIZE': 200, # 给没有请求分页的用
'LIMIT_SUPER_PRIV': False, 'LIMIT_SUPER_PRIV': False,

View File

@@ -4,7 +4,7 @@ from rest_framework.pagination import LimitOffsetPagination
class MaxLimitOffsetPagination(LimitOffsetPagination): class MaxLimitOffsetPagination(LimitOffsetPagination):
max_limit = settings.MAX_LIMIT_PER_PAGE max_limit = settings.MAX_PAGE_SIZE
def get_count(self, queryset): def get_count(self, queryset):
try: try:
@@ -13,17 +13,14 @@ class MaxLimitOffsetPagination(LimitOffsetPagination):
return len(queryset) return len(queryset)
def paginate_queryset(self, queryset, request, view=None): def paginate_queryset(self, queryset, request, view=None):
if request.query_params.get('format') in ['csv', 'xlsx']:
self.default_limit = settings.MAX_LIMIT_PER_PAGE
return super().paginate_queryset(queryset, request, view)
if view and hasattr(view, 'page_max_limit'): if view and hasattr(view, 'page_max_limit'):
self.max_limit = view.page_max_limit self.max_limit = view.page_max_limit
# 自定义的 api view就默认不约束分页了
if getattr(view, 'action', None) != 'list' and not getattr(view, 'default_limit', None):
self.default_limit = None
if view and hasattr(view, 'page_default_limit'): if view and hasattr(view, 'page_default_limit'):
self.default_limit = view.page_default_limit self.default_limit = view.page_default_limit
if view and hasattr(view, 'default_limit'):
self.default_limit = view.default_limit
return super().paginate_queryset(queryset, request, view) return super().paginate_queryset(queryset, request, view)

View File

@@ -225,7 +225,9 @@ SESSION_RSA_PUBLIC_KEY_NAME = 'jms_public_key'
OPERATE_LOG_ELASTICSEARCH_CONFIG = CONFIG.OPERATE_LOG_ELASTICSEARCH_CONFIG OPERATE_LOG_ELASTICSEARCH_CONFIG = CONFIG.OPERATE_LOG_ELASTICSEARCH_CONFIG
MAX_LIMIT_PER_PAGE = CONFIG.MAX_LIMIT_PER_PAGE MAX_LIMIT_PER_PAGE = CONFIG.MAX_LIMIT_PER_PAGE
DEFAULT_PAGE_SIZE = CONFIG.DEAFULT_LIMIT_PER_PAGE MAX_PAGE_SIZE = CONFIG.MAX_PAGE_SIZE
DEFAULT_PAGE_SIZE = CONFIG.DEFAULT_PAGE_SIZE
PERM_TREE_REGEN_INTERVAL = CONFIG.PERM_TREE_REGEN_INTERVAL PERM_TREE_REGEN_INTERVAL = CONFIG.PERM_TREE_REGEN_INTERVAL
# Magnus DB Port # Magnus DB Port

View File

@@ -47,7 +47,7 @@ REST_FRAMEWORK = {
'DATETIME_FORMAT': '%Y/%m/%d %H:%M:%S %z', 'DATETIME_FORMAT': '%Y/%m/%d %H:%M:%S %z',
'DATETIME_INPUT_FORMATS': ['%Y/%m/%d %H:%M:%S %z', 'iso-8601', '%Y-%m-%d %H:%M:%S %z'], 'DATETIME_INPUT_FORMATS': ['%Y/%m/%d %H:%M:%S %z', 'iso-8601', '%Y-%m-%d %H:%M:%S %z'],
'DEFAULT_PAGINATION_CLASS': 'jumpserver.rewriting.pagination.MaxLimitOffsetPagination', 'DEFAULT_PAGINATION_CLASS': 'jumpserver.rewriting.pagination.MaxLimitOffsetPagination',
'PAGE_SIZE': CONFIG.DEFAULT_PAGE_SIZE, 'PAGE_SIZE': None,
'EXCEPTION_HANDLER': 'common.drf.exc_handlers.common_exception_handler', 'EXCEPTION_HANDLER': 'common.drf.exc_handlers.common_exception_handler',
'DEFAULT_SCHEMA_CLASS': 'jumpserver.views.schema.CustomAutoSchema', 'DEFAULT_SCHEMA_CLASS': 'jumpserver.views.schema.CustomAutoSchema',
} }

View File

@@ -24,7 +24,7 @@ class ContentTypeViewSet(JMSModelViewSet):
rbac_perms = { rbac_perms = {
'resources': 'rbac.view_contenttype', 'resources': 'rbac.view_contenttype',
} }
page_default_limit = None page_no_limit = True
can_labeled_content_type = [] can_labeled_content_type = []
model = ContentType model = ContentType

View File

@@ -28,7 +28,7 @@ class RoleViewSet(JMSModelViewSet):
rbac_perms = { rbac_perms = {
'users': 'rbac.view_rolebinding' 'users': 'rbac.view_rolebinding'
} }
default_limit = None page_no_limit = True
def perform_destroy(self, instance): def perform_destroy(self, instance):
from orgs.utils import tmp_to_root_org from orgs.utils import tmp_to_root_org

View File

@@ -29,8 +29,7 @@ class HostMixin:
('list', 'terminal.view_applethost'), ('list', 'terminal.view_applethost'),
('retrieve', 'terminal.view_applethost'), ('retrieve', 'terminal.view_applethost'),
) )
page_no_limit = True
default_limit = None
def get_permissions(self): def get_permissions(self):
if self.kwargs.get('host') and settings.DEBUG: if self.kwargs.get('host') and settings.DEBUG: