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
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)
|
|
|