from rest_framework import viewsets, permissions, status, filters from rest_framework.decorators import action from rest_framework.response import Response from .models import Comment, Rating, Like, Favorite from .serializers import ( CommentSerializer, CommentCreateSerializer, RatingSerializer, RatingCreateSerializer, LikeSerializer, FavoriteSerializer, FavoriteCreateSerializer ) class CommentViewSet(viewsets.ModelViewSet): """ViewSet for Comment model.""" queryset = Comment.objects.select_related('author') permission_classes = [permissions.IsAuthenticatedOrReadOnly] filter_backends = [filters.SearchFilter, filters.OrderingFilter, filters.DjangoFilterBackend] search_fields = ['content'] filterset_fields = ['target_type', 'target_id', 'ai_status'] ordering_fields = ['created_at'] ordering = ['-created_at'] def get_queryset(self): # Only show approved comments if not self.request.user.is_authenticated: return self.queryset.filter(ai_status='approved') # Admins see all if self.request.user.is_admin(): return self.queryset # Regular users see approved + their own return self.queryset.filter( Q(ai_status='approved') | Q(author=self.request.user) ).distinct() def get_serializer_class(self): if self.action == 'create': return CommentCreateSerializer return CommentSerializer def perform_create(self, serializer): serializer.save() def perform_update(self, serializer): # Only allow updating own comments if str(serializer.instance.author.id) != str(self.request.user.id): from rest_framework.exceptions import PermissionDenied raise PermissionDenied("You can only update your own comments") serializer.save() def perform_destroy(self, instance): # Only allow deleting own comments or by admin if (not self.request.user.is_admin() and str(instance.author.id) != str(self.request.user.id)): from rest_framework.exceptions import PermissionDenied raise PermissionDenied("You can only delete your own comments") instance.delete() @action(detail=True, methods=['post']) def approve_ai(self, request, pk=None): """Approve comment by AI (simulated).""" if not request.user.is_ai_auditor(): return Response( {'detail': 'Only AI auditors can approve comments'}, status=status.HTTP_403_FORBIDDEN ) comment = self.get_object() comment.approve_ai() return Response({'message': 'Comment approved by AI'}) @action(detail=True, methods=['post']) def reject_ai(self, request, pk=None): """Reject comment by AI (simulated).""" if not request.user.is_ai_auditor(): return Response( {'detail': 'Only AI auditors can reject comments'}, status=status.HTTP_403_FORBIDDEN ) comment = self.get_object() reason = request.data.get('reason', 'Content violates guidelines') comment.reject_ai(reason) return Response({'message': 'Comment rejected by AI'}) class RatingViewSet(viewsets.ModelViewSet): """ViewSet for Rating model.""" queryset = Rating.objects.select_related('user') serializer_class = RatingSerializer permission_classes = [permissions.IsAuthenticatedOrReadOnly] filter_backends = [filters.SearchFilter, filters.OrderingFilter, filters.DjangoFilterBackend] filterset_fields = ['target_type', 'target_id', 'user'] ordering_fields = ['created_at'] ordering = ['-created_at'] def get_queryset(self): # Admins see all if self.request.user.is_admin(): return self.queryset # Regular users see their own ratings return self.queryset.filter(user=self.request.user) def get_serializer_class(self): if self.action == 'create': return RatingCreateSerializer return RatingSerializer def perform_create(self, serializer): serializer.save() def perform_destroy(self, instance): # Only allow deleting own ratings if str(instance.user.id) != str(self.request.user.id): from rest_framework.exceptions import PermissionDenied raise PermissionDenied("You can only delete your own ratings") instance.delete() @action(detail=False, methods=['get']) def my_ratings(self, request): """Get current user's ratings.""" ratings = Rating.objects.filter(user=request.user).select_related() serializer = self.get_serializer(ratings, many=True) return Response(serializer.data) class LikeViewSet(viewsets.ModelViewSet): """ViewSet for Like model.""" queryset = Like.objects.select_related('user') serializer_class = LikeSerializer permission_classes = [permissions.IsAuthenticated] filter_backends = [filters.OrderingFilter, filters.DjangoFilterBackend] filterset_fields = ['target_type', 'target_id', 'user'] ordering_fields = ['created_at'] ordering = ['-created_at'] def get_queryset(self): # Admins see all if self.request.user.is_admin(): return self.queryset # Regular users see their own likes return self.queryset.filter(user=self.request.user) @action(detail=False, methods=['post']) def toggle(self, request): """Toggle like on a target.""" target_type = request.data.get('target_type') target_id = request.data.get('target_id') if not target_type or not target_id: return Response( {'detail': 'target_type and target_id are required'}, status=status.HTTP_400_BAD_REQUEST ) like, created = Like.objects.get_or_create( user=request.user, target_type=target_type, target_id=target_id ) if not created: like.delete() return Response({'message': 'Unliked', 'liked': False}) return Response({'message': 'Liked', 'liked': True}) @action(detail=False, methods=['get']) def my_likes(self, request): """Get current user's likes.""" likes = Like.objects.filter(user=request.user).select_related() serializer = self.get_serializer(likes, many=True) return Response(serializer.data) class FavoriteViewSet(viewsets.ModelViewSet): """ViewSet for Favorite model.""" queryset = Favorite.objects.select_related('user') serializer_class = FavoriteSerializer permission_classes = [permissions.IsAuthenticated] filter_backends = [filters.OrderingFilter, filters.DjangoFilterBackend] filterset_fields = ['target_type', 'target_id', 'user'] ordering_fields = ['created_at'] ordering = ['-created_at'] def get_queryset(self): # Admins see all if self.request.user.is_admin(): return self.queryset # Regular users see their own favorites return self.queryset.filter(user=self.request.user) def get_serializer_class(self): if self.action == 'create': return FavoriteCreateSerializer return FavoriteSerializer @action(detail=False, methods=['post']) def toggle(self, request): """Toggle favorite on a target.""" serializer = FavoriteCreateSerializer(data=request.data) if serializer.is_valid(): result = serializer.save() if result is None: return Response({'message': 'Unfavorited', 'favorited': False}) return Response({'message': 'Favorited', 'favorited': True}) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @action(detail=False, methods=['get']) def my_favorites(self, request): """Get current user's favorites.""" favorites = Favorite.objects.filter(user=request.user).select_related() serializer = FavoriteSerializer(favorites, many=True) return Response(serializer.data)