|
|
|
@ -1,4 +1,4 @@ |
|
|
|
from django.db.models import Count, Q |
|
|
|
from django.db.models import Count, Q, Avg, OuterRef, Subquery, F |
|
|
|
from rest_framework.permissions import IsAuthenticated , AllowAny |
|
|
|
from rest_framework.authentication import TokenAuthentication |
|
|
|
from rest_framework.response import Response |
|
|
|
@ -158,11 +158,34 @@ class BookListView(ListAPIView): |
|
|
|
# status=True |
|
|
|
# ).values_list('content_id', flat=True) |
|
|
|
|
|
|
|
# Filter books by these IDs |
|
|
|
queryset = queryset.filter(id__in=bookmarked_ids) |
|
|
|
# Import Rate here to avoid circular imports if any |
|
|
|
from apps.bookmark.models.rate import Rate |
|
|
|
|
|
|
|
# Subquery to calculate average rating for each book |
|
|
|
avg_rating = Rate.objects.filter( |
|
|
|
service=Rate.ServiceChoices.LIBRARY, |
|
|
|
content_id=OuterRef('pk'), |
|
|
|
status=True |
|
|
|
).order_by().values('content_id').annotate( |
|
|
|
avg_rate=Avg('rate') |
|
|
|
).values('avg_rate') |
|
|
|
|
|
|
|
queryset = queryset.annotate(average_rate=Subquery(avg_rating)) |
|
|
|
|
|
|
|
# Sort mapping |
|
|
|
sort_mapping = { |
|
|
|
'most_popular': [F('download_count').desc(nulls_last=True), '-created_at'], |
|
|
|
'newest': ['-created_at'], |
|
|
|
'most_view': [F('view_count').desc(nulls_last=True), '-created_at'], |
|
|
|
'most_rated': [F('average_rate').desc(nulls_last=True), '-created_at'], |
|
|
|
} |
|
|
|
|
|
|
|
# Sort by parameter |
|
|
|
sort = self.request.query_params.get('sort', '-pin,-created_at') |
|
|
|
|
|
|
|
if sort in sort_mapping: |
|
|
|
queryset = queryset.order_by(*sort_mapping[sort]) |
|
|
|
else: |
|
|
|
# Allowed sort fields |
|
|
|
allowed_sorts = [ |
|
|
|
'created_at', '-created_at', 'view_count', '-view_count', |
|
|
|
|