from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from django.core.files.storage import default_storage from django.conf import settings from PIL import Image import os from .models import Project, Asset from .serializers import ProjectSerializer, ProjectDetailSerializer, AssetSerializer @api_view(['GET', 'POST']) def project_list(request): """获取项目列表或创建新项目""" if request.method == 'GET': projects = Project.objects.all() serializer = ProjectSerializer(projects, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = ProjectSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['GET', 'PUT', 'DELETE']) def project_detail(request, pk): """获取、更新或删除项目""" try: project = Project.objects.get(pk=pk) except Project.DoesNotExist: return Response({'error': 'Project not found'}, status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = ProjectDetailSerializer(project) return Response(serializer.data) elif request.method == 'PUT': serializer = ProjectSerializer(project, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': project.delete() return Response(status=status.HTTP_204_NO_CONTENT) @api_view(['GET', 'POST']) def asset_list(request, project_pk): """获取项目素材列表或上传新素材""" try: project = Project.objects.get(pk=project_pk) except Project.DoesNotExist: return Response({'error': 'Project not found'}, status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': assets = project.assets.all() serializer = AssetSerializer(assets, many=True) return Response(serializer.data) elif request.method == 'POST': if 'file' not in request.FILES: return Response({'error': 'No file provided'}, status=status.HTTP_400_BAD_REQUEST) file = request.FILES['file'] asset_type = request.POST.get('asset_type', 'unknown') asset_key = request.POST.get('asset_key', 'unknown') # 创建项目素材目录 project_media_dir = os.path.join('projects', str(project.id), asset_type) full_dir = os.path.join(settings.MEDIA_ROOT, project_media_dir) os.makedirs(full_dir, exist_ok=True) # 保存文件 file_name = f"{asset_key}_{file.name}" file_path = os.path.join(project_media_dir, file_name) saved_path = default_storage.save(file_path, file) # 获取图片尺寸 try: img = Image.open(file) width, height = img.size except: width, height = None, None # 创建Asset记录 asset = Asset.objects.create( project=project, asset_type=asset_type, asset_key=asset_key, file_path=saved_path, file_name=file_name, width=width, height=height ) serializer = AssetSerializer(asset) return Response(serializer.data, status=status.HTTP_201_CREATED) @api_view(['GET', 'DELETE']) def asset_detail(request, project_pk, asset_pk): """获取或删除单个素材""" try: project = Project.objects.get(pk=project_pk) asset = project.assets.get(pk=asset_pk) except (Project.DoesNotExist, Asset.DoesNotExist): return Response({'error': 'Asset not found'}, status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = AssetSerializer(asset) return Response(serializer.data) elif request.method == 'DELETE': # 删除文件 if asset.file_path: file_full_path = os.path.join(settings.MEDIA_ROOT, asset.file_path) if os.path.exists(file_full_path): os.remove(file_full_path) asset.delete() return Response(status=status.HTTP_204_NO_CONTENT)