feat(core/backend): serve TOS presigned preview_url for asset files

AssetFile.preview_url was stored blank on upload, so all thumbnails fell back to placeholders.
Make preview_url a SerializerMethodField that signs a TOS GET URL from object_key on read
(falls back to stored value, or "" when TOS unconfigured / no key). Verified: presigned URL
for an existing object returns HTTP 200 image/png.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209 2026-06-05 14:39:06 +08:00
parent 78fd7ee13d
commit 8bcf7615df

View File

@ -1,9 +1,23 @@
from django.conf import settings
from rest_framework import serializers
from .models import Asset, AssetFile
from .storage import TosStorage
_tos_storage = None
def _tos():
global _tos_storage
if _tos_storage is None:
_tos_storage = TosStorage()
return _tos_storage
class AssetFileSerializer(serializers.ModelSerializer):
preview_url = serializers.SerializerMethodField()
class Meta:
model = AssetFile
fields = [
@ -18,7 +32,28 @@ class AssetFileSerializer(serializers.ModelSerializer):
"preview_url",
"is_primary",
]
read_only_fields = fields
read_only_fields = [
"id",
"object_key",
"bucket",
"content_type",
"size_bytes",
"width",
"height",
"duration_ms",
"is_primary",
]
def get_preview_url(self, obj):
# 存储字段优先(如外部已写入绝对 URL);否则用 object_key 实时签发 TOS 预签名 GET URL
if obj.preview_url:
return obj.preview_url
if not obj.object_key or not settings.TOS.get("endpoint"):
return ""
try:
return _tos().presigned_get_url(object_key=obj.object_key)
except Exception:
return ""
class AssetSerializer(serializers.ModelSerializer):