diff --git a/apps/assets/api/category.py b/apps/assets/api/category.py index abc2b12e6..242840716 100644 --- a/apps/assets/api/category.py +++ b/apps/assets/api/category.py @@ -16,7 +16,6 @@ class CategoryViewSet(ListModelMixin, JMSGenericViewSet): 'types': TypeSerializer, } permission_classes = (IsValidUser,) - default_limit = None def get_queryset(self): return AllTypes.categories() diff --git a/apps/assets/api/favorite_asset.py b/apps/assets/api/favorite_asset.py index 176af897d..51658114b 100644 --- a/apps/assets/api/favorite_asset.py +++ b/apps/assets/api/favorite_asset.py @@ -14,7 +14,7 @@ class FavoriteAssetViewSet(BulkModelViewSet): serializer_class = FavoriteAssetSerializer permission_classes = (IsValidUser,) filterset_fields = ['asset'] - default_limit = None + page_no_limit = True def dispatch(self, request, *args, **kwargs): with tmp_to_root_org(): diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py index c5a21f4ed..dba009449 100644 --- a/apps/assets/api/platform.py +++ b/apps/assets/api/platform.py @@ -43,7 +43,7 @@ class AssetPlatformViewSet(JMSModelViewSet): 'ops_methods': 'assets.view_platform', 'filter_nodes_assets': 'assets.view_platform', } - default_limit = None + page_no_limit = True def get_queryset(self): # 因为没有走分页逻辑,所以需要这里 prefetch diff --git a/apps/common/api/mixin.py b/apps/common/api/mixin.py index c10fde7b1..73af89eaa 100644 --- a/apps/common/api/mixin.py +++ b/apps/common/api/mixin.py @@ -5,6 +5,7 @@ from contextlib import nullcontext from itertools import chain from typing import Callable +from django.conf import settings from django.db import models from django.db.models.signals import m2m_changed from common.utils import is_uuid @@ -103,9 +104,20 @@ class QuerySetMixin: if not pk or is_uuid(pk) or pk.isdigit(): return super().get_object() 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): - return super().get_queryset() + # 如果分页器没有设置 limit,则不限制 + 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): queryset = super().filter_queryset(queryset) @@ -114,6 +126,7 @@ class QuerySetMixin: if self.action == 'metadata': queryset = queryset.none() queryset = self.setup_eager_loading(queryset) + queryset = self.limit_queryset_if_no_page(queryset) return queryset def setup_eager_loading(self, queryset, is_paginated=False): diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 4271d3584..bdf6773e2 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -692,8 +692,9 @@ class Config(dict): 'FTP_FILE_MAX_STORE': 0, # API 分页 - 'MAX_LIMIT_PER_PAGE': 10000, - 'DEFAULT_PAGE_SIZE': 10, + 'MAX_LIMIT_PER_PAGE': 10000, # 给导出用 + 'MAX_PAGE_SIZE': 1000, + 'DEFAULT_PAGE_SIZE': 200, # 给没有请求分页的用 'LIMIT_SUPER_PRIV': False, diff --git a/apps/jumpserver/rewriting/pagination.py b/apps/jumpserver/rewriting/pagination.py index f90b5ef71..838bcbf54 100644 --- a/apps/jumpserver/rewriting/pagination.py +++ b/apps/jumpserver/rewriting/pagination.py @@ -4,7 +4,7 @@ from rest_framework.pagination import LimitOffsetPagination class MaxLimitOffsetPagination(LimitOffsetPagination): - max_limit = settings.MAX_LIMIT_PER_PAGE + max_limit = settings.MAX_PAGE_SIZE def get_count(self, queryset): try: @@ -13,17 +13,14 @@ class MaxLimitOffsetPagination(LimitOffsetPagination): return len(queryset) 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'): 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'): 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) diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index f1e0cd137..fa65491f7 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -225,7 +225,9 @@ SESSION_RSA_PUBLIC_KEY_NAME = 'jms_public_key' OPERATE_LOG_ELASTICSEARCH_CONFIG = CONFIG.OPERATE_LOG_ELASTICSEARCH_CONFIG 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 # Magnus DB Port diff --git a/apps/jumpserver/settings/libs.py b/apps/jumpserver/settings/libs.py index e19caf1d9..65a768493 100644 --- a/apps/jumpserver/settings/libs.py +++ b/apps/jumpserver/settings/libs.py @@ -47,7 +47,7 @@ REST_FRAMEWORK = { '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'], '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', 'DEFAULT_SCHEMA_CLASS': 'jumpserver.views.schema.CustomAutoSchema', } diff --git a/apps/labels/api.py b/apps/labels/api.py index eb34d3621..e7b26a759 100644 --- a/apps/labels/api.py +++ b/apps/labels/api.py @@ -24,7 +24,7 @@ class ContentTypeViewSet(JMSModelViewSet): rbac_perms = { 'resources': 'rbac.view_contenttype', } - page_default_limit = None + page_no_limit = True can_labeled_content_type = [] model = ContentType diff --git a/apps/rbac/api/role.py b/apps/rbac/api/role.py index 36b06a9b5..27ae45646 100644 --- a/apps/rbac/api/role.py +++ b/apps/rbac/api/role.py @@ -28,7 +28,7 @@ class RoleViewSet(JMSModelViewSet): rbac_perms = { 'users': 'rbac.view_rolebinding' } - default_limit = None + page_no_limit = True def perform_destroy(self, instance): from orgs.utils import tmp_to_root_org diff --git a/apps/terminal/api/applet/relation.py b/apps/terminal/api/applet/relation.py index 4b7b7dcba..45d2c7cee 100644 --- a/apps/terminal/api/applet/relation.py +++ b/apps/terminal/api/applet/relation.py @@ -29,8 +29,7 @@ class HostMixin: ('list', 'terminal.view_applethost'), ('retrieve', 'terminal.view_applethost'), ) - - default_limit = None + page_no_limit = True def get_permissions(self): if self.kwargs.get('host') and settings.DEBUG: