from rest_framework import viewsets, permissions, status from rest_framework.response import Response from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from api.models import Project from api.serializers import ProjectSerializer, ProjectDetailSerializer import os import shutil from django.conf import settings @method_decorator(csrf_exempt, name='dispatch') class ProjectViewSet(viewsets.ModelViewSet): """项目视图集""" ###add## queryset = Project.objects.none() ################### queryset = Project.objects.all() permission_classes = [permissions.IsAuthenticated] def get_serializer_class(self): if self.action == 'retrieve': return ProjectDetailSerializer return ProjectSerializer # def get_queryset(self): # """只返回当前用户的项目""" # return Project.objects.filter(user=self.request.user) def get_queryset(self): # drf-yasg 生成 schema 时不要走真实查询 if getattr(self, 'swagger_fake_view', False): return Project.objects.none() user = self.request.user if not user or not user.is_authenticated: return Project.objects.none() return Project.objects.filter(user=user) def perform_create(self, serializer): """创建项目时,设置用户为当前用户""" serializer.save(user=self.request.user) def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) # 添加next_steps字段,指示用户可以执行的下一步操作 response_data = serializer.data response_data['next_steps'] = [ { "step": "data_upload", "url": f"/api/projects/{response_data['id']}/data/upload/", "description": "上传数据" } ] return Response(response_data, status=status.HTTP_201_CREATED, headers=headers) def destroy(self, request, *args, **kwargs): """删除项目,包括其关联的所有文件和数据""" instance = self.get_object() # 删除项目相关文件夹 user_id = request.user.id project_id = str(instance.id) project_dir = os.path.join(settings.MEDIA_ROOT, f'users/{user_id}/projects/{project_id}') if os.path.exists(project_dir): try: shutil.rmtree(project_dir) except Exception as e: return Response( {"error": {"code": "delete_files_error", "message": f"删除项目文件时出错: {str(e)}"}}, status=status.HTTP_500_INTERNAL_SERVER_ERROR ) # 执行原始的销毁操作(删除数据库记录) instance.delete() return Response( {"status": "success", "message": "项目已成功删除"}, status=status.HTTP_204_NO_CONTENT )