You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

116 lines
3.7 KiB

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)