添加全能创作功能

This commit is contained in:
Azmat@qq.com
2026-09-03 13:11:46 +08:00
parent 22ed2833ad
commit 6a628b0ca7
53 changed files with 9115 additions and 108 deletions
+76 -1
View File
@@ -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",
]