review_status/review_remote_id 加 db_default='';review_error(TEXT,MySQL 不许默认值)改可空。根因:旧代码插入 Asset 不带 review_* 列 → NOT NULL 无默认 → MySQL 1364。迁移已应用到 dev 共享库,补提交迁移文件保持库/代码一致。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
116 lines
4.3 KiB
Python
116 lines
4.3 KiB
Python
from django.db import models
|
|
|
|
from apps.common.models import TeamOwnedModel, TimeStampedModel
|
|
|
|
|
|
class Asset(TeamOwnedModel):
|
|
class Type(models.TextChoices):
|
|
IMAGE = "image", "Image"
|
|
VIDEO = "video", "Video"
|
|
AUDIO = "audio", "Audio"
|
|
SUBTITLE = "subtitle", "Subtitle"
|
|
DOCUMENT = "document", "Document"
|
|
|
|
class Source(models.TextChoices):
|
|
UPLOAD = "upload", "Upload"
|
|
AI_GENERATED = "ai_generated", "AI Generated"
|
|
EXPORTED = "exported", "Exported"
|
|
SYSTEM = "system", "System"
|
|
|
|
class Category(models.TextChoices):
|
|
PERSON = "person", "Person"
|
|
SCENE = "scene", "Scene"
|
|
PRODUCT_IMAGE = "product_image", "Product Image"
|
|
VIDEO_CLIP = "video_clip", "Video Clip"
|
|
FINAL_VIDEO = "final_video", "Final Video"
|
|
UPLOAD = "upload", "Upload"
|
|
UNCATEGORIZED = "uncategorized", "Uncategorized"
|
|
|
|
name = models.CharField(max_length=255)
|
|
asset_type = models.CharField(max_length=24, choices=Type.choices)
|
|
source = models.CharField(max_length=32, choices=Source.choices)
|
|
category = models.CharField(max_length=32, choices=Category.choices, default=Category.UNCATEGORIZED)
|
|
description = models.TextField(blank=True)
|
|
origin_task = models.ForeignKey(
|
|
"ai.AITask",
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name="generated_assets",
|
|
)
|
|
metadata = models.JSONField(default=dict, blank=True)
|
|
is_deleted = models.BooleanField(default=False)
|
|
# 火山人像素材库审核(仅真人 person 资产):"" = 未送审 / processing 审核中 / active 绿盾通过 / failed 红标(需改提示词重生)
|
|
review_status = models.CharField(max_length=16, blank=True, db_default="")
|
|
review_remote_id = models.CharField(max_length=128, blank=True, db_default="")
|
|
review_error = models.TextField(blank=True, null=True, default="") # TEXT 不能有 DB 默认值(MySQL 1101),改用可空容忍「漏带字段」的插入
|
|
|
|
def __str__(self) -> str:
|
|
return self.name
|
|
|
|
|
|
class AssetReviewGroup(TimeStampedModel):
|
|
"""一团队一火山人像素材组(真人资产审核统一上传到这里,单组可放 500 万)。"""
|
|
|
|
team = models.OneToOneField("accounts.Team", on_delete=models.CASCADE, related_name="review_group")
|
|
remote_group_id = models.CharField(max_length=128)
|
|
name = models.CharField(max_length=128, blank=True)
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.team_id}:{self.remote_group_id}"
|
|
|
|
|
|
class AssetFile(TimeStampedModel):
|
|
asset = models.ForeignKey(Asset, on_delete=models.CASCADE, related_name="files")
|
|
object_key = models.CharField(max_length=512)
|
|
bucket = models.CharField(max_length=128)
|
|
content_type = models.CharField(max_length=128, blank=True)
|
|
size_bytes = models.BigIntegerField(default=0)
|
|
checksum = models.CharField(max_length=128, blank=True)
|
|
width = models.PositiveIntegerField(null=True, blank=True)
|
|
height = models.PositiveIntegerField(null=True, blank=True)
|
|
duration_ms = models.PositiveIntegerField(null=True, blank=True)
|
|
preview_url = models.URLField(blank=True)
|
|
is_primary = models.BooleanField(default=True)
|
|
|
|
class Meta:
|
|
indexes = [
|
|
models.Index(fields=["bucket", "object_key"]),
|
|
]
|
|
|
|
def __str__(self) -> str:
|
|
return self.object_key
|
|
|
|
|
|
class AssetTag(TimeStampedModel):
|
|
team = models.ForeignKey("accounts.Team", on_delete=models.CASCADE, related_name="asset_tags")
|
|
name = models.CharField(max_length=64)
|
|
|
|
class Meta:
|
|
unique_together = [("team", "name")]
|
|
|
|
def __str__(self) -> str:
|
|
return self.name
|
|
|
|
|
|
class AssetTagging(TimeStampedModel):
|
|
asset = models.ForeignKey(Asset, on_delete=models.CASCADE, related_name="taggings")
|
|
tag = models.ForeignKey(AssetTag, on_delete=models.CASCADE, related_name="taggings")
|
|
|
|
class Meta:
|
|
unique_together = [("asset", "tag")]
|
|
|
|
|
|
class AssetUsage(TimeStampedModel):
|
|
asset = models.ForeignKey(Asset, on_delete=models.CASCADE, related_name="usages")
|
|
project = models.ForeignKey(
|
|
"projects.Project",
|
|
on_delete=models.CASCADE,
|
|
null=True,
|
|
blank=True,
|
|
related_name="asset_usages",
|
|
)
|
|
usage_type = models.CharField(max_length=64)
|
|
context = models.JSONField(default=dict, blank=True)
|
|
|