from rest_framework import viewsets, permissions, status, filters from rest_framework.decorators import action from rest_framework.response import Response from django.db.models import Q from .models import ( ModeratorApplication, ModeratorPermission, ModeratorSupport, PermissionRestriction ) from .serializers import ( ModeratorApplicationSerializer, ModeratorApplicationCreateSerializer, ModeratorPermissionSerializer, ModeratorSupportSerializer, PermissionRestrictionSerializer ) class ModeratorApplicationViewSet(viewsets.ModelViewSet): """ViewSet for ModeratorApplication model.""" permission_classes = [permissions.IsAuthenticated] filter_backends = [filters.SearchFilter, filters.OrderingFilter, filters.DjangoFilterBackend] search_fields = ['applicant__username', 'region__name'] filterset_fields = ['status', 'rank', 'region'] ordering_fields = ['created_at', 'deadline'] ordering = ['-created_at'] def get_queryset(self): queryset = ModeratorApplication.objects.select_related('applicant', 'region', 'reviewed_by') # Admins see all if self.request.user.is_admin(): return queryset # Regular users see their own applications return queryset.filter(applicant=self.request.user) def get_serializer_class(self): if self.action == 'create': return ModeratorApplicationCreateSerializer return ModeratorApplicationSerializer def perform_create(self, serializer): serializer.save() @action(detail=True, methods=['post']) def support(self, request, pk=None): """Support a moderator application.""" application = self.get_object() # Check if application is still pending if application.status != 'pending': return Response( {'detail': 'Can only support pending applications'}, status=status.HTTP_400_BAD_REQUEST ) # Check if already supported if ModeratorSupport.objects.filter( supporter=request.user, application=application ).exists(): return Response( {'detail': 'Already supported this application'}, status=status.HTTP_400_BAD_REQUEST ) serializer = ModeratorSupportSerializer(data={'application': application.id}) if serializer.is_valid(): serializer.save() return Response({'message': 'Application supported', 'support_count': application.support_count}) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action(detail=True, methods=['post']) def approve(self, request, pk=None): """Approve moderator application (admin only).""" if not request.user.is_admin(): return Response( {'detail': 'Only admins can approve applications'}, status=status.HTTP_403_FORBIDDEN ) application = self.get_object() if application.status != 'pending': return Response( {'detail': 'Can only approve pending applications'}, status=status.HTTP_400_BAD_REQUEST ) # Check if has enough support if not application.has_enough_support(): return Response( {'detail': 'Not enough support votes'}, status=status.HTTP_400_BAD_REQUEST ) # Create moderator permission from .models import ModeratorPermission ModeratorPermission.objects.create( moderator=application.applicant, region=application.region, rank=application.rank, status='active' ) # Update application status application.status = 'approved' application.reviewed_by = request.user application.reviewed_at = timezone.now() application.save() return Response({'message': 'Application approved, moderator permissions granted'}) @action(detail=True, methods=['post']) def reject(self, request, pk=None): """Reject moderator application (admin only).""" if not request.user.is_admin(): return Response( {'detail': 'Only admins can reject applications'}, status=status.HTTP_403_FORBIDDEN ) application = self.get_object() if application.status != 'pending': return Response( {'detail': 'Can only reject pending applications'}, status=status.HTTP_400_BAD_REQUEST ) application.status = 'rejected' application.reviewed_by = request.user application.reviewed_at = timezone.now() application.save() return Response({'message': 'Application rejected'}) @action(detail=False, methods=['get']) def my_applications(self, request): """Get current user's applications.""" applications = ModeratorApplication.objects.filter( applicant=request.user ).select_related('region') serializer = self.get_serializer(applications, many=True) return Response(serializer.data) class ModeratorPermissionViewSet(viewsets.ReadOnlyModelViewSet): """ViewSet for ModeratorPermission model (read-only).""" queryset = ModeratorPermission.objects.select_related('moderator', 'region') serializer_class = ModeratorPermissionSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): # Admins see all if self.request.user.is_admin(): return self.queryset # Moderators see their own permissions return self.queryset.filter(moderator=self.request.user) @action(detail=False, methods=['get']) def my_permissions(self, request): """Get current user's moderator permissions.""" permissions = ModeratorPermission.objects.filter( moderator=request.user, status='active' ).select_related('region') serializer = self.get_serializer(permissions, many=True) return Response(serializer.data) class PermissionRestrictionViewSet(viewsets.ModelViewSet): """ViewSet for PermissionRestriction model.""" queryset = PermissionRestriction.objects.select_related('operator', 'target_moderator') serializer_class = PermissionRestrictionSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): # Admins see all if self.request.user.is_admin(): return self.queryset # Moderators see restrictions on themselves return self.queryset.filter(target_moderator=self.request.user) def perform_create(self, serializer): # Only admins can create restrictions if not self.request.user.is_admin(): from rest_framework.exceptions import PermissionDenied raise PermissionDenied("Only admins can create restrictions") serializer.save(operator=self.request.user)