Browse Source

fix(api): exclude empty playlists without items from public video and podcast endpoints

master
Mohsen Taba 3 weeks ago
parent
commit
8f45feeeb3
  1. 7
      apps/podcast/serializers.py
  2. 25
      apps/podcast/views.py
  3. 7
      apps/video/serializers.py
  4. 30
      apps/video/views.py

7
apps/podcast/serializers.py

@ -13,7 +13,7 @@ class PodcastCategoryListSerializer(serializers.ModelSerializer):
fields = ['id', 'title', 'slug', 'playlist_count'] fields = ['id', 'title', 'slug', 'playlist_count']
def get_playlist_count(self, obj): def get_playlist_count(self, obj):
return obj.playlists.filter(status=True).count()
return obj.playlists.filter(status=True, playlist_items__isnull=False).distinct().count()
class PodcastListSerializer(serializers.ModelSerializer): class PodcastListSerializer(serializers.ModelSerializer):
@ -298,7 +298,10 @@ class MiddlePodcastCollectionSerializer(serializers.ModelSerializer):
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists') fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists')
def get_playlists(self, obj): def get_playlists(self, obj):
playlists = obj.related_playlists.filter(status=True).order_by('order', '-created_at')
playlists = obj.related_playlists.filter(
status=True,
playlist_items__isnull=False
).distinct().order_by('order', '-created_at')
return PodcastPlaylistListSerializer(playlists, many=True, context=self.context).data return PodcastPlaylistListSerializer(playlists, many=True, context=self.context).data

25
apps/podcast/views.py

@ -1,4 +1,4 @@
from django.db.models import Q
from django.db.models import Q, Prefetch
from rest_framework import generics, status from rest_framework import generics, status
from rest_framework.authentication import TokenAuthentication from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import action from rest_framework.decorators import action
@ -45,7 +45,12 @@ class PodcastCategoryListAPIView(generics.ListAPIView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return PodcastCategory.objects.filter(status=True).order_by('order')
return PodcastCategory.objects.filter(status=True).prefetch_related(
Prefetch(
'playlists',
queryset=PodcastPlaylist.objects.filter(status=True, playlist_items__isnull=False).distinct()
)
).order_by('order')
@ -72,7 +77,8 @@ class PinnedPodcastCollectionListView(generics.ListAPIView):
return PinnedPodcastCollection.objects.filter( return PinnedPodcastCollection.objects.filter(
status=True, status=True,
display_position=PodcastCollection.DisplayPosition.PINNED, display_position=PodcastCollection.DisplayPosition.PINNED,
podcasts__status=True
related_playlists__status=True,
related_playlists__playlist_items__isnull=False
).distinct().order_by('order', '-created_at') ).distinct().order_by('order', '-created_at')
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -122,8 +128,10 @@ class MiddlePodcastCollectionListView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
return PodcastCollection.objects.filter( return PodcastCollection.objects.filter(
status=True, status=True,
display_position=PodcastCollection.DisplayPosition.MIDDLE
).order_by('order', '-created_at')
display_position=PodcastCollection.DisplayPosition.MIDDLE,
related_playlists__status=True,
related_playlists__playlist_items__isnull=False
).distinct().order_by('order', '-created_at')
class PodcastListAPIView(generics.ListAPIView): class PodcastListAPIView(generics.ListAPIView):
@ -186,7 +194,10 @@ class PodcastListAPIView(generics.ListAPIView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
queryset = PodcastPlaylist.objects.filter(status=True)
queryset = PodcastPlaylist.objects.filter(
status=True,
playlist_items__isnull=False
).distinct()
# Search by title if search parameter is provided # Search by title if search parameter is provided
search_query = self.request.query_params.get('search', None) search_query = self.request.query_params.get('search', None)
@ -261,7 +272,7 @@ class PodcastDetailAPIView(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return PodcastPlaylist.objects.all()
return PodcastPlaylist.objects.filter(status=True, playlist_items__isnull=False).distinct()
def retrieve(self, request, *args, **kwargs): def retrieve(self, request, *args, **kwargs):
instance = self.get_object() instance = self.get_object()

7
apps/video/serializers.py

@ -13,7 +13,7 @@ class VideoCategoryListSerializer(serializers.ModelSerializer):
fields = ['id', 'title', 'slug', 'playlist_count'] fields = ['id', 'title', 'slug', 'playlist_count']
def get_playlist_count(self, obj): def get_playlist_count(self, obj):
return obj.playlists.filter(status=True).count()
return obj.playlists.filter(status=True, playlist_items__isnull=False).distinct().count()
class VideoListSerializer(serializers.ModelSerializer): class VideoListSerializer(serializers.ModelSerializer):
@ -322,7 +322,10 @@ class MiddleVideoCollectionSerializer(serializers.ModelSerializer):
fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists') fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists')
def get_playlists(self, obj): def get_playlists(self, obj):
playlists = obj.related_playlists.filter(status=True).order_by('order', '-created_at')
playlists = obj.related_playlists.filter(
status=True,
playlist_items__isnull=False
).distinct().order_by('order', '-created_at')
# Filter by bookmarks if requested in context # Filter by bookmarks if requested in context
is_bookmark = self.context.get('is_bookmark') is_bookmark = self.context.get('is_bookmark')

30
apps/video/views.py

@ -1,4 +1,4 @@
from django.db.models import Q
from django.db.models import Q, Prefetch
from rest_framework import generics, status from rest_framework import generics, status
from rest_framework.authentication import TokenAuthentication from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import action from rest_framework.decorators import action
@ -45,10 +45,13 @@ class VideoCategoryListAPIView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
""" """
Optimized queryset with prefetch_related for playlists
Optimized queryset with prefetch_related for playlists with items
""" """
return VideoCategory.objects.filter(status=True).prefetch_related( return VideoCategory.objects.filter(status=True).prefetch_related(
'playlists'
Prefetch(
'playlists',
queryset=VideoPlaylist.objects.filter(status=True, playlist_items__isnull=False).distinct()
)
).order_by('order') ).order_by('order')
@ -85,7 +88,8 @@ class PinnedVideoCollectionListView(generics.ListAPIView):
queryset = PinnedVideoCollection.objects.filter( queryset = PinnedVideoCollection.objects.filter(
status=True, status=True,
display_position=VideoCollection.DisplayPosition.PINNED, display_position=VideoCollection.DisplayPosition.PINNED,
related_playlists__status=True
related_playlists__status=True,
related_playlists__playlist_items__isnull=False
).distinct().order_by('order', '-created_at') ).distinct().order_by('order', '-created_at')
# Filter by bookmarks if requested # Filter by bookmarks if requested
@ -155,8 +159,10 @@ class MiddleVideoCollectionListView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
return VideoCollection.objects.filter( return VideoCollection.objects.filter(
status=True, status=True,
display_position=VideoCollection.DisplayPosition.MIDDLE
).order_by('order', '-created_at')
display_position=VideoCollection.DisplayPosition.MIDDLE,
related_playlists__status=True,
related_playlists__playlist_items__isnull=False
).distinct().order_by('order', '-created_at')
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
@ -235,7 +241,10 @@ class VideoPlaylistListAPIView(generics.ListAPIView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
queryset = VideoPlaylist.objects.filter(status=True).order_by('order', '-created_at')
queryset = VideoPlaylist.objects.filter(
status=True,
playlist_items__isnull=False
).distinct().order_by('order', '-created_at')
# Search by title if search parameter is provided # Search by title if search parameter is provided
search_query = self.request.query_params.get('search', None) search_query = self.request.query_params.get('search', None)
@ -344,7 +353,10 @@ class VideoListAPIView(generics.ListAPIView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
queryset = VideoPlaylist.objects.filter(status=True).order_by('order', '-created_at')
queryset = VideoPlaylist.objects.filter(
status=True,
playlist_items__isnull=False
).distinct().order_by('order', '-created_at')
# Search by title if search parameter is provided # Search by title if search parameter is provided
search_query = self.request.query_params.get('search', None) search_query = self.request.query_params.get('search', None)
@ -413,7 +425,7 @@ class VideoPlaylistDetailAPIView(generics.RetrieveAPIView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return VideoPlaylist.objects.filter(status=True)
return VideoPlaylist.objects.filter(status=True, playlist_items__isnull=False).distinct()
def retrieve(self, request, *args, **kwargs): def retrieve(self, request, *args, **kwargs):
instance = self.get_object() instance = self.get_object()

Loading…
Cancel
Save