# ViewSet 分页限制重构 ## 概述 为了防止前端无限制地请求大量数据,对所有 ViewSet 实施统一的分页限制策略。 **日期**: 2025-12-25 ## 改动内容 ### 1. 新增基类 (`flower/viewsets.py`) 创建了三个带分页限制的 ViewSet 基类: - **`LimitedLimitOffsetPagination`**: 自定义分页类 - `default_limit = 100`: 默认每页返回 100 条 - `max_limit = 100`: 最大每页返回 100 条 - **`LimitedModelViewSet`**: 继承自 `viewsets.ModelViewSet` - 自动应用 `LimitedLimitOffsetPagination` - 用于标准 CRUD 操作 - **`LimitedReadOnlyModelViewSet`**: 继承自 `viewsets.ReadOnlyModelViewSet` - 自动应用 `LimitedLimitOffsetPagination` - 用于只读场景 - **`LimitedGenericViewSet`**: 继承自 `viewsets.GenericViewSet` - 自动应用 `LimitedLimitOffsetPagination` - 用于自定义 actions ### 2. 更新所有 ViewSet #### api_v1 模块 - ✅ `UploadFileViewSet` → 继承 `LimitedGenericViewSet` - ✅ `StateParameterViewSet` → 继承 `LimitedModelViewSet` - ✅ `ProductQuickViewSet` → 继承 `LimitedGenericViewSet` - ✅ `StateViewSet` → 继承 `LimitedModelViewSet` - ✅ `ProcessViewSet` → 继承 `LimitedModelViewSet` - ✅ `BusinessObjectViewSet` → 继承 `LimitedModelViewSet` - ✅ `PrintingOrderViewSet` → 继承 `LimitedModelViewSet` - ✅ `PrintingJobViewSet` → 继承 `LimitedModelViewSet` - ✅ `PlateOrderViewSet` → 继承 `LimitedModelViewSet` - ✅ `MDYPlateOrderStagingViewSet` → 继承 `LimitedReadOnlyModelViewSet` #### api_man 模块 - ✅ `BaseViewSet` → 继承 `LimitedModelViewSet` - ✅ `QuickInputViewSet` → 继承 `LimitedModelViewSet` - ✅ 所有继承自 `BaseViewSet` 的 ViewSet 自动获得分页限制: - `ProductViewSet` - `WareHouseViewSet` - `ProductCategoryViewSet` - `SupplierViewSet` - `EmployeeViewSet` - `EmployeeTypeViewSet` - `CustomerViewSet` - `VehicleTypeViewSet` - `BankAccountViewSet` - `DeviceInfoViewSet` - `VehicleTransportRecordViewSet` - `UserProfileViewSet` #### api_v2 模块 - 暂无 ViewSet(使用 APIView) ### 3. 移除冗余配置 所有 ViewSet 中显式设置的 `pagination_class = LimitOffsetPagination` 已被移除,因为基类已经提供了更好的分页配置。 ## 技术细节 ### 分页行为 **之前**: ```python class MyViewSet(viewsets.ModelViewSet): pagination_class = LimitOffsetPagination # 无限制,可能导致性能问题 ``` **之后**: ```python class MyViewSet(LimitedModelViewSet): # 自动继承分页限制,无需显式声明 pass ``` ### API 请求示例 ```bash # 默认返回 100 条 GET /api/v1/printing-orders/ # 请求 50 条(正常) GET /api/v1/printing-orders/?limit=50 # 请求 200 条 → 自动限制为 100 条 GET /api/v1/printing-orders/?limit=200 # 使用 offset 进行翻页 GET /api/v1/printing-orders/?limit=100&offset=100 ``` ### 响应格式 ```json { "count": 1234, "next": "http://example.com/api/v1/printing-orders/?limit=100&offset=100", "previous": null, "results": [...] } ``` ## 注意事项 1. **向后兼容**:所有现有 API 调用仍然有效 2. **自动限制**:即使前端请求 `limit=10000`,后端也只会返回最多 100 条 3. **新增 ViewSet**:今后创建新的 ViewSet 应继承 `flower.viewsets` 中的基类 4. **特殊需求**:如果某个 ViewSet 需要不同的限制,可以覆盖 `pagination_class` ## 文件清单 ### 新增文件 - `flower/viewsets.py` ### 修改文件 - `api_v1/views/upload.py` - `api_v1/views/parameters.py` - `api_v1/views/products/views.py` - `api_v1/views/stateflow/state.py` - `api_v1/views/stateflow/process.py` - `api_v1/views/stateflow/business_object.py` - `api_v1/views/printing/views.py` - `api_v1/views/mingdaoyun/plate_order_staging.py` - `api_man/views.py` ## 测试建议 ```bash # 测试默认分页 curl "http://localhost:8000/api/v1/printing-orders/" -H "Authorization: Bearer TOKEN" # 测试限制超出 curl "http://localhost:8000/api/v1/printing-orders/?limit=500" -H "Authorization: Bearer TOKEN" # 验证返回的数据量不超过 100 条 ``` ## 下一步 如果需要调整限制数量(如改为 50 或 200),只需修改 `flower/viewsets.py` 中的 `LimitedLimitOffsetPagination` 类即可: ```python class LimitedLimitOffsetPagination(LimitOffsetPagination): default_limit = 50 # 修改这里 max_limit = 50 # 修改这里 ```