forked from erp-dev/erp
123 lines
3.9 KiB
Python
123 lines
3.9 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 flower.viewsets import LimitedGenericViewSet
|
|
from api_v1.models import UploadedFile
|
|
from api_v1.serializers import UploadedFileSerializer, FileUploadSerializer
|
|
|
|
|
|
class UploadFileViewSet(LimitedGenericViewSet,
|
|
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
|
|
)
|