1
0
forked from erp-dev/erp

fix: business.object_id maybe null, missing parameters when plate-Order cloned

This commit is contained in:
2025-12-17 11:02:07 +08:00
parent 639efe8421
commit 51fad953c3
24 changed files with 13247 additions and 47 deletions

View File

@@ -4,6 +4,7 @@ Stateflow 序列化器
from rest_framework import serializers
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from stateflow import models
@@ -356,7 +357,14 @@ class BusinessObjectCreateUpdateSerializer(serializers.ModelSerializer):
}
def validate(self, attrs):
"""验证 content_type 和 object_id 的一致性"""
"""
业务约束BusinessObject 必须绑定到一个“真实业务对象”。
背景:
- DB 允许 content_type/object_id 为空仅为历史兼容;
- 但业务逻辑要求 BusinessObject 可通过 (content_type, object_id) 追溯到被追踪对象;
否则整个流程实例将失去意义,并可能导致下游逻辑崩溃。
"""
content_type = attrs.get('content_type')
content_type_str = attrs.get('content_type_str')
object_id = attrs.get('object_id')
@@ -371,17 +379,26 @@ class BusinessObjectCreateUpdateSerializer(serializers.ModelSerializer):
raise serializers.ValidationError({
'content_type_str': f'无效的 content_type 格式: {content_type_str}'
})
# 验证:如果提供了 content_type必须提供 object_id
if content_type and not object_id:
# 以“最终值”做校验partial_update 未传字段时要以 instance 的现有值为准
if self.instance is not None:
if 'content_type' not in attrs:
content_type = self.instance.content_type
if 'object_id' not in attrs:
object_id = self.instance.object_id
# 强制绑定content_type/object_id 均不可为空
if content_type is None or object_id is None:
raise serializers.ValidationError({
'object_id': '提供了关联对象类型必须同时提供对象ID'
'detail': 'BusinessObject 必须绑定关联对象content_type 与 object_id 均为必填且不可为空)'
})
# 验证:如果提供了 object_id必须提供 content_type
if object_id and not content_type:
# 强制要求绑定对象存在(避免产生“不可追溯”的悬空绑定)
try:
content_type.get_object_for_this_type(pk=object_id)
except ObjectDoesNotExist:
raise serializers.ValidationError({
'content_type': '提供了对象ID必须同时提供关联对象类型'
'object_id': f'关联对象不存在:{content_type.app_label}.{content_type.model} #{object_id}'
})
# 移除临时字段