from rest_framework import viewsets from utils.page import MyPageNumberPagination from rest_framework.filters import OrderingFilter from django_filters.rest_framework import DjangoFilterBackend from rest_framework.response import Response from rest_framework import status from rest_framework.parsers import MultiPartParser, FormParser from rest_framework.views import APIView import os import uuid from django.conf import settings from .models import Users, AcademicProfile, ResearchGroup, GroupMembership from .filter import UsersFilter, AcademicProfileFilter, ResearchGroupFilter, GroupMembershipFilter from .serializers import UsersGetSerializer,UsersPostSerializer from .serializers import AcademicProfileGetSerializer, AcademicProfilePostSerializer class UserprofileViewSet(viewsets.ModelViewSet): """ 用户档案视图集 retrieve: Response a data list (get) list: Response a data list (all) create: Create a data line (post) delete: Delete a data line (delete) partial_update: Partial_update a data (patch:partial_update) update: Update a data (put:update) """ fliter_backends = (DjangoFilterBackend, OrderingFilter) ordering_fields = ('create_time', 'update_time') filterset_class = UsersFilter pagination_class = MyPageNumberPagination def get_project(self): try: # 表格通道 if 'pk' in self.kwargs: id = self.kwargs.get('pk') return id else: # 用户通道 user = self.request.auth if user.roles == 'USR': return user.user_id else: return None except: return None def get_queryset(self): project_id = self.get_project() if project_id: return Users.objects.filter(user_id=project_id) else: return Users.objects.all() def get_serializer_class(self): if self.action in ['list','retrieve']: return UsersGetSerializer elif self.action in ['create', 'update', 'partial_update']: return UsersPostSerializer else: return UsersGetSerializer def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) # 表格的写法 def update(self, request, *args, **kwargs): if 'pk' in self.kwargs: qs = self.get_object() serializer = self.get_serializer(qs, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK, headers=self.get_success_headers(serializer.data)) else: # 没有qs,应该是管理员和用户更新自己的信息 qs = request.auth serializer = self.get_serializer(qs, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK, headers=self.get_success_headers(serializer.data)) def partial_update(self, request, *args, **kwargs): qs = self.get_object() serializer = self.get_serializer(qs, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data) def destroy(self, request, *args, **kwargs): qs = self.get_object() qs.is_delete = True qs.save() return Response(status=status.HTTP_204_NO_CONTENT) class AvatarUploadView(APIView): parser_classes = [MultiPartParser] def post(self, request): avatar_file = request.FILES.get('avatar') if not avatar_file: return Response({"error": "未上传头像文件"}, status=400) # 生成唯一文件名 ext = os.path.splitext(avatar_file.name)[1] filename = f"{uuid.uuid4().hex}{ext}" # 目标目录 avatars_dir = os.path.join(settings.MEDIA_ROOT, 'avatars') # 确保目录存在 if not os.path.exists(avatars_dir): os.makedirs(avatars_dir) # 保存文件 save_path = os.path.join(avatars_dir, filename) with open(save_path, 'wb+') as destination: for chunk in avatar_file.chunks(): destination.write(chunk) # 返回相对路径(前端会拼接完整URL) avatar_url = f"/avatars/{filename}" # 更新用户头像 user = request.auth user.avatar = avatar_url user.save() # 传递 request 到序列化器上下文 serializer = UsersGetSerializer(user, context={'request': request}) return Response(serializer.data) class AcademicProfileViewSet(viewsets.ModelViewSet): """ 学术资料视图集 retrieve: Response a data list (get) list: Response a data list (all) create: Create a data line (post) delete: Delete a data line (delete) partial_update: Partial_update a data (patch:partial_update) update: Update a data (put:update) """ fliter_backends = (DjangoFilterBackend, OrderingFilter) ordering_fields = ('create_time', 'update_time') filterset_class = AcademicProfileFilter pagination_class = MyPageNumberPagination def get_project(self): try: # 表格通道 if 'pk' in self.kwargs: id = self.kwargs.get('pk') return id else: # 用户通道 user = self.request.auth if user.roles == 'USR': # id= AcademicProfile.objects.filter(user=user).first().id return user.user_id else: return None except: return None def get_queryset(self): project_id = self.get_project() if project_id: return AcademicProfile.objects.filter(user_id=project_id) else: return AcademicProfile.objects.all() def get_serializer_class(self): if self.action in ['list','retrieve']: return AcademicProfileGetSerializer elif self.action in ['create', 'update', 'partial_update']: return AcademicProfilePostSerializer else: return AcademicProfileGetSerializer def update(self, request, *args, **kwargs): if 'pk' in self.kwargs: qs = self.get_object() serializer = self.get_serializer(qs, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK, headers=self.get_success_headers(serializer.data)) else: # 没有qs,应该是管理员和用户更新自己的信息 qs = request.auth AcademicProfile_obj = AcademicProfile.objects.filter(user=qs).first() if not AcademicProfile_obj: AcademicProfile_obj = AcademicProfile.objects.create(user=qs) serializer = self.get_serializer(AcademicProfile_obj, data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK, headers=self.get_success_headers(serializer.data)) def create(self, request, *args, **kwargs): return super().create(request, *args, **kwargs) def partial_update(self, request, *args, **kwargs): return super().partial_update(request, *args, **kwargs) def destroy(self, request, *args, **kwargs): return super().destroy(request, *args, **kwargs)