Browse Source

podcast views for admin panel added

master
Mohsen Taba 1 month ago
parent
commit
ceb294566b
  1. 18
      apps/podcast/migrations/0002_podcast_collections.py
  2. 2
      apps/podcast/models.py
  3. 130
      apps/podcast/serializers_admin.py
  4. 12
      apps/podcast/urls.py
  5. 73
      apps/podcast/views_admin.py

18
apps/podcast/migrations/0002_podcast_collections.py

@ -0,0 +1,18 @@
# Generated by Django 5.2.12 on 2026-06-08 14:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('podcast', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='podcast',
name='collections',
field=models.ManyToManyField(blank=True, related_name='podcasts', to='podcast.podcastcollection', verbose_name='collections'),
),
]

2
apps/podcast/models.py

@ -86,7 +86,7 @@ class Podcast(models.Model):
description = models.TextField(null=True) description = models.TextField(null=True)
categories = models.ManyToManyField(PodcastCategory, related_name='podcasts', verbose_name=_('categories'), blank=True) categories = models.ManyToManyField(PodcastCategory, related_name='podcasts', verbose_name=_('categories'), blank=True)
collections = models.ManyToManyField(PodcastCollection, related_name='podcasts', verbose_name=_('collections'), blank=True)
audio_file = models.FileField(upload_to='podcast/audio/', null=True, blank=True) audio_file = models.FileField(upload_to='podcast/audio/', null=True, blank=True)
audio_time = models.TimeField() audio_time = models.TimeField()

130
apps/podcast/serializers_admin.py

@ -0,0 +1,130 @@
from rest_framework import serializers
from .models import Podcast , PodcastCategory , PodcastCollection
class AbsoluteImageField(serializers.ImageField):
def to_representation(self, value):
if not value:
return None
request = self.context.get("request")
url = value.url if hasattr(value, "url") else str(value)
if request:
return request.build_absolute_uri(url)
return url
class AbsoluteFileField(serializers.FileField):
def to_representation(self, value):
if not value:
return None
request = self.context.get("request")
url = value.url if hasattr(value, "url") else str(value)
if request:
return request.build_absolute_uri(url)
return url
class AdminPodcastCategorySerializer(serializers.ModelSerializer):
class Meta:
model = PodcastCategory
fields = ["id", "title", "slug", "status", "created_at", "updated_at"]
class AdminPodcastCollectionSerializer(serializers.ModelSerializer):
class Meta:
model = PodcastCollection
fields = ["id", "title", "slug", "summary", "display_position", "status", "order", "pin_top"]
class AdminPodcastListSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
audio_file = AbsoluteFileField(required=False, allow_null=True)
categories_detail = AdminPodcastCategorySerializer(source="categories", many=True, read_only=True)
collections_detail = AdminPodcastCollectionSerializer(source="collections", many=True, read_only=True)
class Meta:
model = Podcast
fields = [
"id",
"title",
"slug",
"thumbnail",
"status",
"view_count",
"download_count",
"created_at",
"updated_at",
"categories_detail",
"collections_detail",
"audio_file"
]
read_only_fields = ["id", "view_count", "download_count", "created_at", "updated_at"]
class AdminPodcastDetailSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
audio_file = AbsoluteFileField(required=False, allow_null=True)
audio_time = serializers.TimeField(required=False)
categories = serializers.PrimaryKeyRelatedField(queryset=PodcastCategory.objects.all(), many=True, required=False)
collections = serializers.PrimaryKeyRelatedField(queryset=PodcastCollection.objects.all(), many=True, required=False)
categories_detail = AdminPodcastCategorySerializer(source="categories", many=True, read_only=True)
collections_detail = AdminPodcastCollectionSerializer(source="collections", many=True, read_only=True)
remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False)
remove_audio_file = serializers.BooleanField(write_only=True, required=False, default=False)
class Meta:
model = Podcast
fields = [
"id",
"title",
"slug",
"thumbnail",
"description",
"audio_file",
"audio_time",
"status",
"view_count",
"download_count",
"created_at",
"updated_at",
"categories",
"collections",
"categories_detail",
"collections_detail",
"remove_thumbnail",
"remove_audio_file",
]
read_only_fields = ["id", "view_count", "download_count", "created_at", "updated_at"]
def create(self, validated_data):
validated_data.pop("remove_thumbnail", False)
validated_data.pop("remove_audio_file", False)
categories = validated_data.pop("categories", [])
collections = validated_data.pop("collections", [])
podcast = super().create(validated_data)
if categories:
podcast.categories.set(categories)
if collections:
podcast.collections.set(collections)
return podcast
def update(self, instance, validated_data):
remove_thumbnail = validated_data.pop("remove_thumbnail", False)
remove_audio_file = validated_data.pop("remove_audio_file", False)
categories = validated_data.pop("categories", None)
collections = validated_data.pop("collections", None)
if remove_thumbnail and instance.thumbnail:
instance.thumbnail.delete(save=False)
instance.thumbnail = None
if remove_audio_file and instance.audio_file:
instance.audio_file.delete(save=False)
instance.audio_file = None
podcast = super().update(instance, validated_data)
if categories is not None:
podcast.categories.set(categories)
if collections is not None:
podcast.collections.set(collections)
return podcast

12
apps/podcast/urls.py

@ -1,9 +1,17 @@
from django.urls import path, re_path
from django.urls import path, re_path , include
from rest_framework.routers import SimpleRouter
from .views import * from .views import *
from .views_admin import *
admin_router = SimpleRouter()
admin_router.register(r'podcasts', AdminPodcastViewSet, basename='admin-podcast')
admin_router.register(r'categories', AdminPodcastCategoryViewSet, basename='admin-podcast-category')
admin_router.register(r'collections', AdminPodcastCollectionViewSet, basename='admin-podcast-collection')
app_name = 'podcast' app_name = 'podcast'
urlpatterns = [ urlpatterns = [
path('admin/', include(admin_router.urls)),
path('categories/', PodcastCategoryListAPIView.as_view(), name='category-list'), path('categories/', PodcastCategoryListAPIView.as_view(), name='category-list'),
path('pinned-collections/', PinnedPodcastCollectionListView.as_view(), name='pinned-collection-list'), path('pinned-collections/', PinnedPodcastCollectionListView.as_view(), name='pinned-collection-list'),
path('collections/', MiddlePodcastCollectionListView.as_view(), name='collection-list'), path('collections/', MiddlePodcastCollectionListView.as_view(), name='collection-list'),
@ -14,4 +22,6 @@ urlpatterns = [
# User playlist endpoints # User playlist endpoints
path('user-playlist/', UserPlaylistCreateAPIView.as_view(), name='user-playlist-create'), path('user-playlist/', UserPlaylistCreateAPIView.as_view(), name='user-playlist-create'),
path('user-playlist/list/', UserPlaylistListAPIView.as_view(), name='user-playlist-list'), path('user-playlist/list/', UserPlaylistListAPIView.as_view(), name='user-playlist-list'),
] ]

73
apps/podcast/views_admin.py

@ -0,0 +1,73 @@
from django.db.models import Q
from rest_framework.authentication import TokenAuthentication
from rest_framework.parsers import FormParser, JSONParser, MultiPartParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from apps.account.permissions import IsSuperAdmin
from utils.pagination import StandardResultsSetPagination
from .models import Podcast, PodcastCollection, PodcastCategory
from .serializers_admin import (
AdminPodcastCategorySerializer,
AdminPodcastCollectionSerializer,
AdminPodcastDetailSerializer,
AdminPodcastListSerializer,
)
class AdminPodcastCategoryViewSet(ReadOnlyModelViewSet):
serializer_class = AdminPodcastCategorySerializer
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
pagination_class = None
def get_queryset(self):
return PodcastCategory.objects.all().order_by("title")
class AdminPodcastCollectionViewSet(ReadOnlyModelViewSet):
serializer_class = AdminPodcastCollectionSerializer
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
pagination_class = None
def get_queryset(self):
return PodcastCollection.objects.all().order_by("display_position", "order", "title")
class AdminPodcastViewSet(ModelViewSet):
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
pagination_class = StandardResultsSetPagination
parser_classes = (MultiPartParser, FormParser, JSONParser)
def get_serializer_class(self):
if self.action == "list":
return AdminPodcastListSerializer
return AdminPodcastDetailSerializer
def get_queryset(self):
queryset = Podcast.objects.all().prefetch_related("categories", "collections")
search_query = self.request.query_params.get("search")
if search_query:
queryset = queryset.filter(
Q(title__icontains=search_query)
| Q(slug__icontains=search_query)
| Q(description__icontains=search_query)
)
status_filter = self.request.query_params.get("status")
if status_filter in {"true", "false"}:
queryset = queryset.filter(status=status_filter == "true")
category_id = self.request.query_params.get("category")
if category_id and category_id != "all":
queryset = queryset.filter(categories__id=category_id)
collection_id = self.request.query_params.get("collection")
if collection_id and collection_id != "all":
queryset = queryset.filter(collections__id=collection_id)
return queryset.distinct().order_by("-created_at")
Loading…
Cancel
Save