Browse Source

library sorting added

master
Mohsen Taba 1 month ago
parent
commit
09a5c067d9
  1. 2
      apps/library/doc.py
  2. 29
      apps/library/views.py

2
apps/library/doc.py

@ -52,7 +52,7 @@ category_param = openapi.Parameter(
sort_param = openapi.Parameter(
'sort',
openapi.IN_QUERY,
description="Sort books by field. Options: created_at, -created_at, view_count, -view_count, download_count, -download_count, title, -title, pin, -pin, -pin,-created_at",
description="Sort books by field. Options: most_popular, newest, most_view, most_rated, created_at, -created_at, view_count, -view_count, download_count, -download_count, title, -title, pin, -pin, -pin,-created_at",
type=openapi.TYPE_STRING,
required=False
)

29
apps/library/views.py

@ -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',

Loading…
Cancel
Save