- User ViewSet(个人中心、统计、收藏、评分、搜索) - Region ViewSet(层级查询、树形结构、文章、服务、统计、评分、收藏) - Article ViewSet(创建、提交、审核、评论、点赞、统计) - FeaturedService ViewSet(创建、提交、审核、评论、点赞、评分、统计) - Moderation ViewSets(版主申请、权限、支持、限制) - Interaction ViewSets(评论、评分、点赞、收藏、AI审核) 完整实现权限控制、审核流程和交互功能
197 lines
6.9 KiB
Python
197 lines
6.9 KiB
Python
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) |