from django_filters.rest_framework import DjangoFilterBackend from rest_framework import status, viewsets from rest_framework.decorators import action from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from apps.annotations.models import Bookmark, Note from apps.annotations.permissions import IsOwner from apps.annotations.serializers import ( BookmarkCreateSerializer, BookmarkSerializer, NoteCreateSerializer, NoteSerializer, ) class BookmarkViewSet(viewsets.ModelViewSet): """CRUD for user bookmarks. Users can only manage their own bookmarks.""" permission_classes = [IsAuthenticated, IsOwner] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ["book"] search_fields = ["location_text"] ordering_fields = ["created_at", "page"] ordering = ["-created_at"] def get_serializer_class(self): if self.action == "create": return BookmarkCreateSerializer return BookmarkSerializer def get_queryset(self): return Bookmark.objects.filter(user=self.request.user).select_related( "book" ) def perform_create(self, serializer): serializer.save(user=self.request.user) @action(detail=False, methods=["delete"], url_path="batch-delete") def batch_delete(self, request): """Delete multiple bookmarks by id list.""" ids = request.data.get("ids", []) if not ids: return Response( {"detail": "No ids provided."}, status=status.HTTP_400_BAD_REQUEST ) deleted, _ = Bookmark.objects.filter( id__in=ids, user=request.user ).delete() return Response( {"deleted": deleted}, status=status.HTTP_200_OK ) class NoteViewSet(viewsets.ModelViewSet): """CRUD for user notes. Users can only manage their own notes.""" permission_classes = [IsAuthenticated, IsOwner] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ["book"] search_fields = ["content", "location_text"] ordering_fields = ["created_at", "page"] ordering = ["-created_at"] def get_serializer_class(self): if self.action == "create": return NoteCreateSerializer return NoteSerializer def get_queryset(self): return Note.objects.filter(user=self.request.user).select_related( "book" ) def perform_create(self, serializer): serializer.save(user=self.request.user) @action(detail=False, methods=["delete"], url_path="batch-delete") def batch_delete(self, request): """Delete multiple notes by id list.""" ids = request.data.get("ids", []) if not ids: return Response( {"detail": "No ids provided."}, status=status.HTTP_400_BAD_REQUEST ) deleted, _ = Note.objects.filter( id__in=ids, user=request.user ).delete() return Response( {"deleted": deleted}, status=status.HTTP_200_OK )