添加全能创作功能
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import AITask, ImageConversation, ModelConfig, ModelProvider
|
||||
from .models import (
|
||||
AITask,
|
||||
CreationConversation,
|
||||
CreationMessage,
|
||||
ImageConversation,
|
||||
ModelConfig,
|
||||
ModelProvider,
|
||||
)
|
||||
|
||||
|
||||
class ModelProviderSerializer(serializers.ModelSerializer):
|
||||
@@ -89,3 +96,71 @@ class AITaskSerializer(serializers.ModelSerializer):
|
||||
# batch_id / mode 是显式声明的 SerializerMethodField(本就只读),不能再列进 read_only_fields(DRF 会报错)
|
||||
read_only_fields = [f for f in fields if f not in ("batch_id", "mode")]
|
||||
|
||||
|
||||
|
||||
class CreationMessageSerializer(serializers.ModelSerializer):
|
||||
"""全能创作对话流里的一条消息。前端**按 kind 分发到不同卡片组件**,
|
||||
结构化内容一律在 payload 里(契约 §2),不要从 text 里解析。"""
|
||||
|
||||
class Meta:
|
||||
model = CreationMessage
|
||||
fields = ["id", "role", "kind", "text", "payload", "refs", "task", "seq", "created_at"]
|
||||
read_only_fields = fields
|
||||
|
||||
|
||||
class CreationConversationSerializer(serializers.ModelSerializer):
|
||||
"""会话列表 / 详情。title 可写(重命名);params 创建后也可改(对话页改模型/比例后立刻生效);
|
||||
mode 创建后不可改。"""
|
||||
|
||||
message_count = serializers.SerializerMethodField()
|
||||
cover_url = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = CreationConversation
|
||||
fields = [
|
||||
"id", "title", "mode", "preset", "params", "status",
|
||||
"message_count", "cover_url",
|
||||
"last_active_at", "created_at", "updated_at",
|
||||
]
|
||||
read_only_fields = [
|
||||
"id", "status", "message_count", "cover_url",
|
||||
"last_active_at", "created_at", "updated_at",
|
||||
]
|
||||
|
||||
def get_message_count(self, obj) -> int:
|
||||
cached = getattr(obj, "_message_count", None)
|
||||
return cached if cached is not None else obj.messages.count()
|
||||
|
||||
def get_cover_url(self, obj) -> str:
|
||||
"""历史页封面 = **最新一版**结果(重生成是往下叠加,所以取最后一条 RESULT)。"""
|
||||
last = (
|
||||
obj.messages.filter(kind=CreationMessage.Kind.RESULT)
|
||||
.order_by("-seq")
|
||||
.values_list("payload", flat=True)
|
||||
.first()
|
||||
)
|
||||
if not last:
|
||||
return ""
|
||||
assets = (last or {}).get("assets") or []
|
||||
if not assets:
|
||||
return ""
|
||||
first = assets[0] or {}
|
||||
return first.get("cover") or first.get("url") or ""
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
# mode 定死:允许传但忽略,避免前端误改后顶栏参数与已生成内容对不上
|
||||
validated_data.pop("mode", None)
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
|
||||
class CreationConversationDetailSerializer(CreationConversationSerializer):
|
||||
"""详情:带全量消息,进对话页一次性回填。"""
|
||||
|
||||
messages = CreationMessageSerializer(many=True, read_only=True)
|
||||
pinned_refs = serializers.JSONField(read_only=True)
|
||||
|
||||
class Meta(CreationConversationSerializer.Meta):
|
||||
fields = [*CreationConversationSerializer.Meta.fields, "messages", "pinned_refs"]
|
||||
read_only_fields = [
|
||||
*CreationConversationSerializer.Meta.read_only_fields, "messages", "pinned_refs",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user