You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

256 lines
9.9 KiB

from rest_framework import serializers
from .models import PlaylistItem, Podcast, PodcastCategory, PodcastCollection, PodcastPlaylist
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
class AdminPodcastPlaylistItemPodcastSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
class Meta:
model = Podcast
fields = ["id", "title", "slug", "thumbnail", "audio_time", "status"]
class AdminPodcastPlaylistItemSerializer(serializers.ModelSerializer):
podcast_detail = AdminPodcastPlaylistItemPodcastSerializer(source="podcast", read_only=True)
class Meta:
model = PlaylistItem
fields = ["id", "playlist", "podcast", "priority", "created_at", "updated_at", "podcast_detail"]
read_only_fields = ["id", "created_at", "updated_at", "podcast_detail"]
def validate(self, attrs):
playlist = attrs.get("playlist", getattr(self.instance, "playlist", None))
podcast = attrs.get("podcast", getattr(self.instance, "podcast", None))
if playlist and podcast:
query = PlaylistItem.objects.filter(podcast=podcast).exclude(playlist=playlist)
if self.instance:
query = query.exclude(pk=self.instance.pk)
existing = query.select_related("playlist").first()
if existing:
raise serializers.ValidationError({
"podcast": f'This podcast is already used in playlist "{existing.playlist.title}".',
})
return attrs
class AdminPodcastPlaylistListSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(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)
items_count = serializers.SerializerMethodField()
class Meta:
model = PodcastPlaylist
fields = [
"id",
"title",
"slug",
"thumbnail",
"slogan",
"status",
"order",
"view_count",
"total_time",
"created_at",
"updated_at",
"categories_detail",
"collections_detail",
"items_count",
]
read_only_fields = ["id", "view_count", "total_time", "created_at", "updated_at", "items_count"]
def get_items_count(self, obj):
return obj.playlist_items.count()
class AdminPodcastPlaylistDetailSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=False, allow_null=True)
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)
playlist_items_detail = AdminPodcastPlaylistItemSerializer(source="playlist_items", many=True, read_only=True)
remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False)
class Meta:
model = PodcastPlaylist
fields = [
"id",
"title",
"slug",
"slogan",
"description",
"thumbnail",
"order",
"status",
"view_count",
"total_time",
"created_at",
"updated_at",
"categories",
"collections",
"categories_detail",
"collections_detail",
"playlist_items_detail",
"remove_thumbnail",
]
read_only_fields = ["id", "view_count", "total_time", "created_at", "updated_at", "playlist_items_detail"]
def create(self, validated_data):
validated_data.pop("remove_thumbnail", False)
categories = validated_data.pop("categories", [])
collections = validated_data.pop("collections", [])
playlist = super().create(validated_data)
if categories:
playlist.categories.set(categories)
if collections:
playlist.collections.set(collections)
playlist.total_time = playlist.calculate_total_time()
playlist.save(update_fields=["total_time"])
return playlist
def update(self, instance, validated_data):
remove_thumbnail = validated_data.pop("remove_thumbnail", 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
playlist = super().update(instance, validated_data)
if categories is not None:
playlist.categories.set(categories)
if collections is not None:
playlist.collections.set(collections)
playlist.total_time = playlist.calculate_total_time()
playlist.save(update_fields=["total_time"])
return playlist