53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
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})
|