perf(core): 项目列表改轻量序列化 + 计数走真实 count,根治刷新 2-3s

/api/projects/ 列表此前与详情共用重序列化器(嵌套 阶段/片段/故事板/时间线 + 每资产算 url),
20 个项目把全套关联拉出 → 实测 ~2-3s,正是每次刷新慢的主因。

- 新增 ProjectListSerializer(轻:名/状态/阶段/product/封面/脚本数/镜数);
  ProjectViewSet.get_serializer_class 列表用轻的、详情用全量;
  get_queryset 列表走轻查询(select_related product + annotate 计数,不做那串 12 个重 prefetch)。
  实测 /api/projects/ 2-3s → 0.48s。
- 新增 /api/projects/summary/(total + by_status,只跑 COUNT,不拉项目对象)。
- 计数显示(侧栏徽标 / 仪表盘 总项目·SKU·N 个)改用分页响应的真实 count(productTotal/projectTotal),
  不再用「已加载 20 条」的长度;projects 列表页脚本状态/镜数改读 *_count 字段。

闸:9 页全绿、无瀑布、API 全过;projects 端点提速 ~5x。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-17 19:27:10 +08:00
co-authored by Claude Opus 4.8
parent c62abed536
commit a0ed8666df
7 changed files with 76 additions and 11 deletions
+21
View File
@@ -245,6 +245,27 @@ class ScriptVersionSerializer(serializers.ModelSerializer):
read_only_fields = fields
class ProjectListSerializer(serializers.ModelSerializer):
"""列表/仪表盘/侧栏用的轻量项目序列化:不嵌套 阶段/片段/故事板/时间线(那些只详情页要)。
脚本数/镜数走 annotate 计数(见 ProjectViewSet.get_queryset),避免逐项目拉全套关联(原列表 2-3s)。"""
product_title = serializers.CharField(source="product.title", read_only=True, default="")
cover_preview_url = serializers.SerializerMethodField()
script_version_count = serializers.IntegerField(read_only=True, default=0)
video_segment_count = serializers.IntegerField(read_only=True, default=0)
class Meta:
model = Project
fields = [
"id", "name", "product", "product_title", "cover_preview_url",
"status", "current_stage", "script_version_count", "video_segment_count",
"created_at", "updated_at",
]
def get_cover_preview_url(self, obj) -> str:
return _asset_preview_url(getattr(obj.product, "cover_asset", None)) if obj.product_id else ""
class ProjectSerializer(serializers.ModelSerializer):
stages = ProjectStageSerializer(many=True, read_only=True)
video_segments = VideoSegmentSerializer(many=True, read_only=True)