# 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       # 修改这里
```
