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

157 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 # 修改这里
```