from django.db.models import Q, Count from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.generics import ListAPIView, RetrieveAPIView from rest_framework.filters import SearchFilter from apps.library.models import * from apps.library.serializers import * from apps.library.doc import ( book_list_swagger, book_detail_swagger, category_list_swagger, pinned_collection_list_swagger ) class CategoryListView(ListAPIView): """ API view to list all book categories """ serializer_class = CategorySerializer permission_classes = (IsAuthenticated,) @category_list_swagger def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): return Category.objects.filter( status=True ).annotate( books_count=Count('related_categories') ).order_by('title') class PinnedBookCollectionListView(ListAPIView): """ API view to list pinned book collections with their top 3 book covers """ serializer_class = PinnedBookCollectionSerializer permission_classes = (IsAuthenticated,) pagination_class = None @pinned_collection_list_swagger def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): return BookCollection.objects.filter( status=True, display_position=BookCollection.DisplayPosition.PINNED ).order_by('-order', '-id') class BookListView(ListAPIView): """ API view to list books with filtering and search capabilities """ serializer_class = BookSerializer permission_classes = (IsAuthenticated,) filter_backends = [SearchFilter] search_fields = ['title', 'summary', 'author'] @book_list_swagger def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): queryset = Book.objects.filter(status=True) # Filter by collection if provided collection_id = self.request.query_params.get('collection_id') if collection_id: queryset = queryset.filter(collections__id=collection_id) # Filter by middle collection if requested # if self.request.query_params.get('middle'): # middle_collections = BookCollection.objects.filter( # status=True, # display_position=BookCollection.DisplayPosition.MIDDLE # ) # if middle_collections.exists(): # queryset = queryset.filter(collections__in=middle_collections) # Filter by bottom collection if requested # if self.request.query_params.get('bottom'): # bottom_collections = BookCollection.objects.filter( # status=True, # display_position=BookCollection.DisplayPosition.BOTTOM # ) # if bottom_collections.exists(): # queryset = queryset.filter(collections__in=bottom_collections) return queryset.order_by('-pin', '-created_at') class BookDetailView(RetrieveAPIView): """ API view to retrieve detailed information about a specific book """ serializer_class = BookSerializer permission_classes = (IsAuthenticated,) queryset = Book.objects.filter(status=True) @book_detail_swagger def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def retrieve(self, request, *args, **kwargs): instance = self.get_object() # Increment view count when book details are viewed instance.increment_view_count() serializer = self.get_serializer(instance) return Response(serializer.data)