diff --git a/akarpov/music/api/serializers.py b/akarpov/music/api/serializers.py index 9186f20..370766b 100644 --- a/akarpov/music/api/serializers.py +++ b/akarpov/music/api/serializers.py @@ -271,6 +271,10 @@ def create(self, validated_data): return song_user_rating +class ListSongSlugsSerializer(serializers.Serializer): + slugs = serializers.ListField(child=serializers.SlugField()) + + class ListPlaylistSerializer(serializers.ModelSerializer): class Meta: model = Playlist diff --git a/akarpov/music/api/urls.py b/akarpov/music/api/urls.py index 034da7e..16f4313 100644 --- a/akarpov/music/api/urls.py +++ b/akarpov/music/api/urls.py @@ -14,6 +14,7 @@ ListLikedSongsAPIView, ListPublicPlaylistAPIView, ListSongPlaylistsAPIView, + ListSongSlugsAPIView, ListUserListenedSongsAPIView, RemoveSongFromPlaylistAPIView, RetrieveUpdateDestroyAlbumAPIView, @@ -41,6 +42,7 @@ name="retrieve_update_delete_playlist", ), path("song/", ListCreateSongAPIView.as_view(), name="list_create_song"), + path("song/slugs/", ListSongSlugsAPIView.as_view(), name="list_songs_slugs"), path( "song/", RetrieveUpdateDestroySongAPIView.as_view(), diff --git a/akarpov/music/api/views.py b/akarpov/music/api/views.py index b24e7db..d0b3c4e 100644 --- a/akarpov/music/api/views.py +++ b/akarpov/music/api/views.py @@ -16,6 +16,7 @@ ListenSongSerializer, ListPlaylistSerializer, ListSongSerializer, + ListSongSlugsSerializer, PlaylistSerializer, SongSerializer, ) @@ -80,11 +81,7 @@ def get_queryset(self): return qs.select_related("creator") -class ListCreateSongAPIView(LikedSongsContextMixin, generics.ListCreateAPIView): - serializer_class = ListSongSerializer - permission_classes = [IsAdminOrReadOnly] - pagination_class = StandardResultsSetPagination - +class ListBaseSongAPIView(generics.ListAPIView): def get_queryset(self): search = self.request.query_params.get("search", None) if search: @@ -116,6 +113,14 @@ def get_queryset(self): ) return qs + +class ListCreateSongAPIView( + LikedSongsContextMixin, generics.ListCreateAPIView, ListBaseSongAPIView +): + serializer_class = ListSongSerializer + permission_classes = [IsAdminOrReadOnly] + pagination_class = StandardResultsSetPagination + @extend_schema( parameters=[ OpenApiParameter( @@ -168,6 +173,67 @@ def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) +class ListSongSlugsAPIView(ListBaseSongAPIView): + serializer_class = ListSongSlugsSerializer + permission_classes = [permissions.AllowAny] + + @extend_schema( + parameters=[ + OpenApiParameter( + name="search", + description="Search query", + required=False, + type=str, + ), + OpenApiParameter( + name="sort", + description="Sorting algorithm", + required=False, + type=str, + examples=[ + OpenApiExample( + "Default", + description="by date added", + value=None, + ), + OpenApiExample( + "played", + description="by total times played", + value="played", + ), + OpenApiExample( + "likes", + description="by total likes", + value="likes", + ), + OpenApiExample( + "likes reversed", + description="by total likes", + value="-likes", + ), + OpenApiExample( + "length", + description="by track length", + value="length", + ), + OpenApiExample( + "uploaded", + description="by date uploaded", + value="uploaded", + ), + ], + ), + ] + ) + def get(self, request, *args, **kwargs): + songs = self.get_queryset() + return Response( + data={ + "songs": songs.values_list("slug", flat=True), + } + ) + + class RetrieveUpdateDestroySongAPIView(generics.RetrieveUpdateDestroyAPIView): lookup_field = "slug" lookup_url_kwarg = "slug" diff --git a/akarpov/music/models.py b/akarpov/music/models.py index c87aed4..418c7d9 100644 --- a/akarpov/music/models.py +++ b/akarpov/music/models.py @@ -48,6 +48,7 @@ class Song(BaseImageModel, ShortLinkModel): creator = models.ForeignKey( "users.User", related_name="songs", on_delete=models.SET_NULL, null=True ) + created = models.DateTimeField(auto_now_add=True) meta = models.JSONField(blank=True, null=True) likes = models.IntegerField(default=0) volume = ArrayField(models.IntegerField(), null=True)