1
0
forked from erp-dev/erp
Files
erpnew/api_v1/views/upload.py
2025-11-17 14:34:09 +08:00

122 lines
3.8 KiB
Python

"""
通用文件上传视图
"""
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
)