forked from erp-dev/erp
4.4 KiB
4.4 KiB
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 自动获得分页限制:ProductViewSetWareHouseViewSetProductCategoryViewSetSupplierViewSetEmployeeViewSetEmployeeTypeViewSetCustomerViewSetVehicleTypeViewSetBankAccountViewSetDeviceInfoViewSetVehicleTransportRecordViewSetUserProfileViewSet
api_v2 模块
- 暂无 ViewSet(使用 APIView)
3. 移除冗余配置
所有 ViewSet 中显式设置的 pagination_class = LimitOffsetPagination 已被移除,因为基类已经提供了更好的分页配置。
技术细节
分页行为
之前:
class MyViewSet(viewsets.ModelViewSet):
pagination_class = LimitOffsetPagination # 无限制,可能导致性能问题
之后:
class MyViewSet(LimitedModelViewSet):
# 自动继承分页限制,无需显式声明
pass
API 请求示例
# 默认返回 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
响应格式
{
"count": 1234,
"next": "http://example.com/api/v1/printing-orders/?limit=100&offset=100",
"previous": null,
"results": [...]
}
注意事项
- 向后兼容:所有现有 API 调用仍然有效
- 自动限制:即使前端请求
limit=10000,后端也只会返回最多 100 条 - 新增 ViewSet:今后创建新的 ViewSet 应继承
flower.viewsets中的基类 - 特殊需求:如果某个 ViewSet 需要不同的限制,可以覆盖
pagination_class
文件清单
新增文件
flower/viewsets.py
修改文件
api_v1/views/upload.pyapi_v1/views/parameters.pyapi_v1/views/products/views.pyapi_v1/views/stateflow/state.pyapi_v1/views/stateflow/process.pyapi_v1/views/stateflow/business_object.pyapi_v1/views/printing/views.pyapi_v1/views/mingdaoyun/plate_order_staging.pyapi_man/views.py
测试建议
# 测试默认分页
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 类即可:
class LimitedLimitOffsetPagination(LimitOffsetPagination):
default_limit = 50 # 修改这里
max_limit = 50 # 修改这里