forked from erp-dev/erp
feat: upload api
This commit is contained in:
121
api_v1/views/upload.py
Normal file
121
api_v1/views/upload.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""
|
||||
通用文件上传视图
|
||||
"""
|
||||
from rest_framework import viewsets, status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.parsers import MultiPartParser, FormParser
|
||||
|
||||
from api_v1.models import UploadedFile
|
||||
from api_v1.serializers import UploadedFileSerializer, FileUploadSerializer
|
||||
|
||||
|
||||
class UploadFileViewSet(viewsets.GenericViewSet,
|
||||
viewsets.mixins.CreateModelMixin,
|
||||
viewsets.mixins.RetrieveModelMixin,
|
||||
viewsets.mixins.DestroyModelMixin):
|
||||
"""
|
||||
通用文件上传 ViewSet
|
||||
|
||||
用于上传无法归类到具体业务的文件
|
||||
|
||||
retrieve: 获取单个文件信息
|
||||
create: 上传新文件
|
||||
destroy: 软删除文件
|
||||
|
||||
注意:不支持列表查询和修改操作
|
||||
"""
|
||||
queryset = UploadedFile.objects.all()
|
||||
serializer_class = UploadedFileSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [MultiPartParser, FormParser]
|
||||
|
||||
def get_queryset(self):
|
||||
"""默认不显示已删除的文件"""
|
||||
queryset = super().get_queryset()
|
||||
# 过滤掉已删除的文件
|
||||
queryset = queryset.filter(is_deleted=False)
|
||||
return queryset
|
||||
|
||||
def perform_create(self, serializer):
|
||||
"""创建时自动设置 owner"""
|
||||
uploaded_file = self.request.FILES.get('file')
|
||||
|
||||
# 保存文件并记录元数据
|
||||
serializer.save(
|
||||
owner=self.request.user,
|
||||
original_filename=uploaded_file.name,
|
||||
file_size=uploaded_file.size,
|
||||
content_type=uploaded_file.content_type
|
||||
)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""
|
||||
上传文件
|
||||
|
||||
使用 multipart/form-data 格式上传
|
||||
"""
|
||||
# 验证上传的文件
|
||||
upload_serializer = FileUploadSerializer(data=request.data)
|
||||
upload_serializer.is_valid(raise_exception=True)
|
||||
|
||||
# 创建文件记录
|
||||
file_serializer = self.get_serializer(data={'path': request.FILES['file']})
|
||||
file_serializer.is_valid(raise_exception=True)
|
||||
self.perform_create(file_serializer)
|
||||
|
||||
headers = self.get_success_headers(file_serializer.data)
|
||||
return Response(
|
||||
file_serializer.data,
|
||||
status=status.HTTP_201_CREATED,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
"""软删除文件(标记为已删除,不实际删除)"""
|
||||
instance = self.get_object()
|
||||
instance.is_deleted = True
|
||||
instance.save()
|
||||
|
||||
return Response(
|
||||
{'detail': '文件已标记为删除'},
|
||||
status=status.HTTP_200_OK
|
||||
)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def restore(self, request, pk=None):
|
||||
"""恢复已删除的文件"""
|
||||
instance = self.get_object()
|
||||
|
||||
if not instance.is_deleted:
|
||||
return Response(
|
||||
{'detail': '文件未被删除,无需恢复'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
instance.is_deleted = False
|
||||
instance.save()
|
||||
|
||||
serializer = self.get_serializer(instance)
|
||||
return Response({
|
||||
'detail': '文件已恢复',
|
||||
'data': serializer.data
|
||||
})
|
||||
|
||||
@action(detail=True, methods=['delete'])
|
||||
def permanent_delete(self, request, pk=None):
|
||||
"""永久删除文件(物理删除)"""
|
||||
instance = self.get_object()
|
||||
|
||||
# 删除物理文件
|
||||
if instance.path:
|
||||
instance.path.delete(save=False)
|
||||
|
||||
# 删除数据库记录
|
||||
instance.delete()
|
||||
|
||||
return Response(
|
||||
{'detail': '文件已永久删除'},
|
||||
status=status.HTTP_204_NO_CONTENT
|
||||
)
|
||||
Reference in New Issue
Block a user