1
0
forked from erp-dev/erp
Files
erpnew/docs/REFACTOR_VIEWSET_PAGINATION_2025-12-25.md
2025-12-25 21:36:50 +08:00

4.4 KiB
Raw Blame History

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 已被移除,因为基类已经提供了更好的分页配置。

技术细节

分页行为

之前

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": [...]
}

注意事项

  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

测试建议

# 测试默认分页
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       # 修改这里