forked from erp-dev/erp
fix: business.object_id maybe null, missing parameters when plate-Order cloned
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
"""
|
||||
Printing API 序列化器
|
||||
"""
|
||||
import json
|
||||
from rest_framework import serializers
|
||||
from rest_framework.fields import empty
|
||||
|
||||
from api_v1.models import UploadedFile
|
||||
from api_v1.utils.media import build_public_media_url
|
||||
@@ -52,8 +54,6 @@ def _build_plate_image_payload(items, request_user):
|
||||
return []
|
||||
|
||||
queryset = UploadedFile.objects.filter(id__in=file_ids, is_deleted=False)
|
||||
if request_user and request_user.is_authenticated:
|
||||
queryset = queryset.filter(owner=request_user)
|
||||
|
||||
files_map = {file.id: file for file in queryset}
|
||||
missing = [str(fid) for fid in file_ids if fid not in files_map]
|
||||
@@ -76,6 +76,48 @@ def _build_plate_image_payload(items, request_user):
|
||||
return payload
|
||||
|
||||
|
||||
class PlateImageInputListSerializer(serializers.ListSerializer):
|
||||
"""
|
||||
兼容 plate_image 的多种入参形态(尤其是 multipart/form-data 场景):
|
||||
- JSON:直接传 array
|
||||
- multipart:常见会把数组作为 JSON 字符串传入(例如 '[{"file_id": 1}]')
|
||||
"""
|
||||
|
||||
def to_internal_value(self, data):
|
||||
# allow_null=True 时,None 会先到这里
|
||||
if data is None:
|
||||
return []
|
||||
|
||||
# multipart/form-data 下,前端常把数组序列化成字符串
|
||||
if isinstance(data, str):
|
||||
raw = data.strip()
|
||||
if not raw:
|
||||
return []
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
raise serializers.ValidationError('plate_image 必须是 JSON 数组或可解析为数组的 JSON 字符串')
|
||||
|
||||
# 兼容单个对象
|
||||
if isinstance(data, dict):
|
||||
data = [data]
|
||||
|
||||
return super().to_internal_value(data)
|
||||
|
||||
def get_value(self, dictionary):
|
||||
"""
|
||||
DRF 在 multipart/form-data 下会优先用“HTML list”解析(期望 plate_image[0][file_id] 这类键)。
|
||||
但前端常见做法是直接传一个字段 plate_image='[{"file_id":1}]'(JSON 字符串)。
|
||||
这里做一次兜底:若 HTML list 未解析到值,则回退读取原始键值。
|
||||
"""
|
||||
value = super().get_value(dictionary)
|
||||
if value is empty and hasattr(dictionary, 'get'):
|
||||
raw = dictionary.get(self.field_name, empty)
|
||||
if raw is not empty:
|
||||
return raw
|
||||
return value
|
||||
|
||||
|
||||
class PlateImageInputSerializer(serializers.Serializer):
|
||||
file_id = serializers.IntegerField(min_value=1, help_text='上传文件的 ID')
|
||||
name = serializers.CharField(
|
||||
@@ -85,6 +127,9 @@ class PlateImageInputSerializer(serializers.Serializer):
|
||||
help_text='可选的图片名称,默认使用文件原始名称'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
list_serializer_class = PlateImageInputListSerializer
|
||||
|
||||
|
||||
class PrintingOrderListSerializer(serializers.ModelSerializer):
|
||||
"""印染订单列表序列化器"""
|
||||
@@ -374,6 +419,7 @@ class PlateOrderListSerializer(PlateOrderDesignCodeMixin, serializers.ModelSeria
|
||||
salesperson_name = serializers.CharField(source="salesperson.name", read_only=True)
|
||||
merchandiser_name = serializers.CharField(source="merchandiser.name", read_only=True)
|
||||
designer_name = serializers.CharField(source="designer.name", read_only=True)
|
||||
created_by = serializers.IntegerField(source='created_by_id', read_only=True)
|
||||
status = serializers.CharField(read_only=True)
|
||||
progress_percentage = serializers.IntegerField(read_only=True)
|
||||
process_name = serializers.SerializerMethodField()
|
||||
@@ -401,6 +447,7 @@ class PlateOrderListSerializer(PlateOrderDesignCodeMixin, serializers.ModelSeria
|
||||
'process', 'process_name',
|
||||
'status', 'status_id', 'is_completed', 'has_started', 'last_completed_state',
|
||||
'progress_percentage', 'business_object_id', 'content_type_id',
|
||||
'created_by',
|
||||
'created_at', 'updated_at'
|
||||
]
|
||||
read_only_fields = [
|
||||
@@ -443,6 +490,7 @@ class PlateOrderDetailSerializer(PlateOrderDesignCodeMixin, serializers.ModelSer
|
||||
salesperson_name = serializers.CharField(source="salesperson.name", read_only=True)
|
||||
merchandiser_name = serializers.CharField(source="merchandiser.name", read_only=True)
|
||||
designer_name = serializers.CharField(source="designer.name", read_only=True)
|
||||
created_by = serializers.IntegerField(source='created_by_id', read_only=True)
|
||||
status = serializers.CharField(read_only=True)
|
||||
status_id = serializers.IntegerField(read_only=True)
|
||||
is_completed = serializers.BooleanField(read_only=True)
|
||||
@@ -472,6 +520,7 @@ class PlateOrderDetailSerializer(PlateOrderDesignCodeMixin, serializers.ModelSer
|
||||
'process', 'process_name',
|
||||
'status', 'status_id', 'is_completed', 'has_started',
|
||||
'progress_percentage', 'business_object_id', 'last_completed_state',
|
||||
'created_by',
|
||||
'created_at', 'updated_at'
|
||||
]
|
||||
read_only_fields = [
|
||||
@@ -508,6 +557,7 @@ class PlateOrderCreateUpdateSerializer(serializers.ModelSerializer):
|
||||
allow_null=True,
|
||||
help_text="开版图片列表,需提供已上传的 file_id,可选 name 字段"
|
||||
)
|
||||
created_by = serializers.IntegerField(source='created_by_id', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = models.PlateOrder
|
||||
@@ -523,9 +573,10 @@ class PlateOrderCreateUpdateSerializer(serializers.ModelSerializer):
|
||||
"sample_meter", "required_sample_meters",
|
||||
"required_completion_date", "completion_date",
|
||||
"approval_result", "is_ordered", "customer_feedback",
|
||||
"process"
|
||||
"process",
|
||||
"created_by",
|
||||
]
|
||||
read_only_fields = ["id"]
|
||||
read_only_fields = ["id", "created_by"]
|
||||
|
||||
def validate_plate_image(self, value):
|
||||
return value or []
|
||||
|
||||
Reference in New Issue
Block a user