12 KiB
Stateflow 模块更新日志 - 2025年11月15日
概述
本次更新对 stateflow 模块进行了重大重构,主要涉及数据模型关系调整、新增字段、服务层功能扩展、API 接口增强以及测试优化。
一、数据模型变更
1.1 State 与 StateParameter 关系重构
Migration: 0017_state_parameter_many_to_many
- 变更内容:将 State 与 StateParameter 的关系从 一对多 改为 多对多
- 原设计:StateParameter 通过 ForeignKey 关联到 State(一个参数只能属于一个状态)
- 新设计:State 通过 ManyToManyField 关联 StateParameter(多个状态可以共享同一个参数)
- 数据迁移:清空了旧的测试数据
- 影响范围:
- 模型定义:
State.parameters = models.ManyToManyField(StateParameter) - API 接口:需要使用
parameter_ids进行参数关联 - 序列化器:支持参数列表的读写操作
- 模型定义:
1.2 移除 StateParameter.name 字段
Migration: 0018_remove_stateparameter_name
- 变更原因:
name字段与key字段语义重复 - 保留字段:使用
key作为参数的唯一标识符 - 影响:简化了参数模型,避免了字段冗余
1.3 新增 StateParameter.is_required 字段
Migration: 0019_stateparameter_is_required
- 字段类型:
BooleanField(default=False) - 用途:标记参数是否为必填项
- 应用场景:
- 前端表单验证
- API 可以通过
required_only=true查询参数只获取必填参数 - 业务逻辑中强制验证必填参数的提供
1.4 新增 StateParameter.is_image_path 字段
Migration: 0020_stateparameter_is_image_path
- 字段类型:
BooleanField(default=False) - 用途:标记
value字段是否存储图片 URL 路径 - 应用场景:
- 前端根据此字段决定是否以图片形式渲染
- 支持混合参数类型(文本、图片、附件等)
- 便于后续扩展不同类型的参数
二、current_state 语义修正(重要变更)
2.1 语义变更
原语义:current_state 表示"下一个待执行的节点"(未完成的节点)
新语义:current_state 表示"最后完成的状态"(已完成的节点)
2.2 影响的函数
stateflow/services.py
-
get_business_object_current_state()
- 原逻辑:返回第一个未完成的节点
- 新逻辑:返回最后一个已完成的节点,未开始时返回 None
-
advance_to_next_state()
- 更新:基于新的 current_state 逻辑计算下一个待完成节点
-
get_next_pending_state() (新增函数)
- 用途:获取下一个待执行节点(替代了原 current_state 的部分功能)
-
get_business_object_state_status()
- 移除:删除了 'in_progress' 状态
- 保留:只有 'not_started' 和 'completed' 两种状态
-
get_overall_status()
- 更新:基于新的 current_state 逻辑判断整体状态
-
can_advance_to_next_state()
- 更新:判断逻辑基于新的 current_state 语义
-
get_business_object_state_timeline()
- 更新:时间线生成逻辑适配新语义
stateflow/admin.py
- BusinessObjectAdmin.current_state_display()
- 更新:显示最后完成的状态,未开始时显示"未开始"
2.3 测试更新
- 更新了 34 个既有测试以适配新语义
- 新增 9 个测试用例
- 所有 43 个测试全部通过
三、新增服务层功能
3.1 get_next_pending_state()
位置:stateflow/services.py
def get_next_pending_state(business_object, include_parameters=True):
"""
获取业务对象的下一个待执行节点
参数:
business_object: 业务对象实例
include_parameters: 是否包含节点参数(默认 True)
返回:
dict 或 None: 包含 state, order, parameters(可选)
"""
功能:
- 返回流程中下一个未完成的节点
- 可选择是否包含该节点的参数列表
- 流程完成时返回 None
测试:test_get_next_pending_state() - 已通过
3.2 get_all_pending_states()
位置:stateflow/services.py
def get_all_pending_states(business_object):
"""
获取业务对象的所有待执行节点列表
参数:
business_object: 业务对象实例
返回:
list: 包含所有待执行节点的列表
"""
功能:
- 返回所有尚未完成的节点列表(按顺序)
- 不包含参数信息(减少数据量)
- 适用于显示整体进度
测试:test_get_all_pending_states() - 已通过
3.3 get_state_parameters()
位置:stateflow/services.py
def get_state_parameters(state, required_only=False):
"""
获取状态的参数列表
参数:
state: State 实例
required_only: 是否只返回必填参数(默认 False)
返回:
QuerySet: StateParameter 查询集
"""
功能:
- 获取指定状态的所有参数
- 支持筛选只返回必填参数
- 基于多对多关系查询
测试:test_get_state_parameters() - 已通过
四、新增 API 接口
4.1 获取下一个待执行节点
端点:GET /api/v1/stateflow/business-objects/{id}/next_pending_state/
查询参数:
include_parameters: boolean(默认 true)- 是否包含参数
响应示例:
{
"business_object_id": 1,
"next_state": {
"state": {
"id": 1,
"name": "状态1",
"description": "第一个状态"
},
"order": 0,
"parameters": [
{
"id": 1,
"key": "param1",
"value": "value1",
"is_required": true,
"is_image_path": false
}
]
}
}
测试:test_next_pending_state_api() - 已通过
4.2 获取所有待执行节点
端点:GET /api/v1/stateflow/business-objects/{id}/pending_states/
响应示例:
{
"business_object_id": 1,
"count": 3,
"pending_states": [
{
"state": {"id": 1, "name": "状态1"},
"order": 0
},
{
"state": {"id": 2, "name": "状态2"},
"order": 1
}
]
}
测试:test_pending_states_api() - 已通过
4.3 获取当前状态的参数
端点:GET /api/v1/stateflow/business-objects/{id}/current_state_parameters/
查询参数:
required_only: boolean(默认 false)- 是否只返回必填参数
响应示例:
{
"business_object_id": 1,
"state": {
"id": 1,
"name": "状态1"
},
"count": 2,
"parameters": [
{
"id": 1,
"key": "param1",
"is_required": true
}
]
}
注意:当 business_object 未开始时(current_state 为 None),返回空参数列表和提示消息。
测试:test_current_state_parameters_api() - 已通过
4.4 获取状态的参数列表
端点:GET /api/v1/stateflow/states/{id}/parameters/
查询参数:
required_only: boolean(默认 false)- 是否只返回必填参数
响应示例:
{
"state_id": 1,
"count": 2,
"parameters": [
{
"id": 1,
"key": "param1",
"value": "value1",
"is_required": true,
"is_image_path": false,
"description": "参数描述"
}
]
}
测试:test_state_parameters_api() - 已通过
五、测试优化
5.1 测试文件重组
变更:将 stateflow/tests.py 移动到 stateflow/tests/test_services.py
原因:
- 解决文件与目录命名冲突
- 符合 Django 测试最佳实践
- 便于后续测试文件的组织和扩展
5.2 测试数据管理优化
优化的测试类:StateAPITestCase
改进内容:
- 将重复的测试数据创建移至
setUp()方法 - 创建共享的基础数据:
self.param1,self.param2,self.state1,self.state2 - 避免每个测试方法中重复创建相同数据
- 提高测试执行效率和可维护性
优化前:每个测试方法内部创建 State 和 Parameter 优化后:在 setUp 中创建基础数据,测试方法直接使用
5.3 新增测试用例
文件:stateflow/test_api.py - BusinessObjectNewAPITestCase
包含 4 个新的 API 测试:
test_next_pending_state_api()- 测试获取下一个待执行节点test_pending_states_api()- 测试获取所有待执行节点test_current_state_parameters_api()- 测试获取当前状态参数test_state_parameters_api()- 测试获取状态参数列表
文件:stateflow/tests/test_services.py
新增 3 个服务层测试:
test_get_next_pending_state()- 测试获取下一个待执行节点服务test_get_all_pending_states()- 测试获取所有待执行节点服务test_get_state_parameters()- 测试获取状态参数服务
5.4 测试覆盖率
- 总测试数:43 个
- 测试状态:全部通过 ✓
- 执行时间:约 6.5 秒
- 覆盖模块:
- 数据模型(Model)
- 服务层(Services)
- API 接口(Views)
- 序列化器(Serializers)
六、受影响的文件清单
6.1 模型层
stateflow/models.py- State 和 StateParameter 关系及字段变更
6.2 服务层
stateflow/services.py- current_state 逻辑修正 + 3 个新函数
6.3 序列化器
stateflow/serializers.py- 适配多对多关系和新字段
6.4 管理后台
stateflow/admin.py- current_state 显示逻辑更新
6.5 API 视图
api_v1/views/stateflow/business_object.py- 新增 3 个 actionapi_v1/views/stateflow/state.py- 新增 1 个 action
6.6 测试文件
stateflow/tests/test_services.py- 服务层测试(重组 + 新增)stateflow/test_api.py- API 测试(优化 + 新增)stateflow/tests/test_step_back.py- 更新适配新语义stateflow/tests/test_step_back_api.py- 更新适配新语义
6.7 数据库迁移
0017_state_parameter_many_to_many.py0018_remove_stateparameter_name.py0019_stateparameter_is_required.py0020_stateparameter_is_image_path.py
七、向后兼容性
7.1 破坏性变更
- StateParameter.state 字段已移除 - 不再支持一对多关系
- StateParameter.name 字段已移除 - 请使用
key字段 - current_state 语义变更 - 从"下一个待执行"变为"最后完成的"
- 移除 'in_progress' 状态 - 只保留 'not_started' 和 'completed'
7.2 迁移建议
- 如果代码中使用了
business_object.get_current_state()期望获取"下一个待执行节点",请改用get_next_pending_state(business_object) - 如果代码中引用了
parameter.state,请改用parameter.states.all()获取关联的状态列表 - 如果代码中使用了
parameter.name,请改用parameter.key
八、后续工作计划
8.1 待验证模块
- api_man 模块:需要检查其中可能存在的 State 和 StateParameter 相关接口,确保兼容本次变更
8.2 待扩展功能
- printing 模块依赖更新:验证 printing 模块对 stateflow 的依赖是否需要调整
- 参数验证逻辑:实现基于
is_required的自动验证机制 - 图片参数处理:完善
is_image_path的前后端集成
九、总结
本次更新显著提升了 stateflow 模块的灵活性和可维护性:
- 更灵活的参数管理:多对多关系允许参数复用
- 更明确的语义:current_state 现在准确表示"已完成到哪里"
- 更强大的 API:新增 4 个接口满足不同查询需求
- 更完善的测试:43 个测试确保代码质量
- 更清晰的代码组织:测试文件重组,数据管理优化
所有变更已通过完整测试验证,可以安全部署。