import os import uuid from django.conf import settings from rest_framework.decorators import api_view, permission_classes, parser_classes from rest_framework.permissions import IsAuthenticated from rest_framework.parsers import MultiPartParser from rest_framework.response import Response from rest_framework import status ALLOWED_IMAGE_TYPES = { 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp', } MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB @api_view(['POST']) @permission_classes([IsAuthenticated]) @parser_classes([MultiPartParser]) def upload_image(request): file = request.FILES.get('file') if not file: return Response({'detail': '未提供文件'}, status=status.HTTP_400_BAD_REQUEST) if file.content_type not in ALLOWED_IMAGE_TYPES: return Response( {'detail': '仅支持 JPG/PNG/GIF/WEBP/BMP 格式的图片'}, status=status.HTTP_400_BAD_REQUEST, ) if file.size > MAX_FILE_SIZE: return Response( {'detail': '文件大小不能超过 10MB'}, status=status.HTTP_400_BAD_REQUEST, ) ext = os.path.splitext(file.name)[1].lower() filename = f"{uuid.uuid4().hex}{ext}" relative_path = f"uploads/{filename}" full_path = os.path.join(settings.MEDIA_ROOT, relative_path) os.makedirs(os.path.dirname(full_path), exist_ok=True) with open(full_path, 'wb+') as dest: for chunk in file.chunks(): dest.write(chunk) url = request.build_absolute_uri(f"/{settings.MEDIA_URL}{relative_path}") return Response({'url': url, 'path': relative_path})