diff --git a/apps/podcast/serializers.py b/apps/podcast/serializers.py index f718175..a9b9f6f 100755 --- a/apps/podcast/serializers.py +++ b/apps/podcast/serializers.py @@ -13,7 +13,7 @@ class PodcastCategoryListSerializer(serializers.ModelSerializer): fields = ['id', 'title', 'slug', 'playlist_count'] 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): @@ -298,7 +298,10 @@ class MiddlePodcastCollectionSerializer(serializers.ModelSerializer): fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists') 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 diff --git a/apps/podcast/views.py b/apps/podcast/views.py index 55847a3..8655381 100644 --- a/apps/podcast/views.py +++ b/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.authentication import TokenAuthentication from rest_framework.decorators import action @@ -45,7 +45,12 @@ class PodcastCategoryListAPIView(generics.ListAPIView): return super().get(request, *args, **kwargs) 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( status=True, display_position=PodcastCollection.DisplayPosition.PINNED, - podcasts__status=True + related_playlists__status=True, + related_playlists__playlist_items__isnull=False ).distinct().order_by('order', '-created_at') def list(self, request, *args, **kwargs): @@ -122,8 +128,10 @@ class MiddlePodcastCollectionListView(generics.ListAPIView): def get_queryset(self): return PodcastCollection.objects.filter( 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): @@ -186,7 +194,10 @@ class PodcastListAPIView(generics.ListAPIView): return super().get(request, *args, **kwargs) 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_query = self.request.query_params.get('search', None) @@ -261,7 +272,7 @@ class PodcastDetailAPIView(Gone410ViewMixin, CanonicalSlugViewSetMixin, generics return super().get(request, *args, **kwargs) 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): instance = self.get_object() diff --git a/apps/video/serializers.py b/apps/video/serializers.py index 86f6ff0..758d064 100644 --- a/apps/video/serializers.py +++ b/apps/video/serializers.py @@ -13,7 +13,7 @@ class VideoCategoryListSerializer(serializers.ModelSerializer): fields = ['id', 'title', 'slug', 'playlist_count'] 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): @@ -322,7 +322,10 @@ class MiddleVideoCollectionSerializer(serializers.ModelSerializer): fields = ('id', 'title', 'slug', 'summary', 'status', 'order', 'playlists') 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 is_bookmark = self.context.get('is_bookmark') diff --git a/apps/video/views.py b/apps/video/views.py index dd46577..7417bfe 100644 --- a/apps/video/views.py +++ b/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.authentication import TokenAuthentication from rest_framework.decorators import action @@ -45,10 +45,13 @@ class VideoCategoryListAPIView(generics.ListAPIView): 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( - 'playlists' + Prefetch( + 'playlists', + queryset=VideoPlaylist.objects.filter(status=True, playlist_items__isnull=False).distinct() + ) ).order_by('order') @@ -85,7 +88,8 @@ class PinnedVideoCollectionListView(generics.ListAPIView): queryset = PinnedVideoCollection.objects.filter( status=True, 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') # Filter by bookmarks if requested @@ -155,8 +159,10 @@ class MiddleVideoCollectionListView(generics.ListAPIView): def get_queryset(self): return VideoCollection.objects.filter( 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): @@ -235,7 +241,10 @@ class VideoPlaylistListAPIView(generics.ListAPIView): return super().get(request, *args, **kwargs) 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_query = self.request.query_params.get('search', None) @@ -344,7 +353,10 @@ class VideoListAPIView(generics.ListAPIView): return super().get(request, *args, **kwargs) 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_query = self.request.query_params.get('search', None) @@ -413,7 +425,7 @@ class VideoPlaylistDetailAPIView(generics.RetrieveAPIView): return super().get(request, *args, **kwargs) 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): instance = self.get_object()