diff --git a/savepointradio/api/serializers/profiles.py b/savepointradio/api/serializers/profiles.py index 4d8387d..f61db15 100644 --- a/savepointradio/api/serializers/profiles.py +++ b/savepointradio/api/serializers/profiles.py @@ -38,6 +38,10 @@ class FavoriteSongSerializer(Serializer): song = IntegerField() +class RateSongSerializer(Serializer): + value = IntegerField(min_value=0, max_value=5, required=False) + + class HistorySerializer(ModelSerializer): profile = BasicProfileSerializer() song = BasicSongRetrieveSerializer() @@ -61,7 +65,3 @@ class BasicSongRatingsSerializer(ModelSerializer): class Meta: model = Rating fields = ('created_date', 'profile', 'value') - - -class RateSongSerializer(Serializer): - rating = IntegerField(min_value=0, max_value=5) diff --git a/savepointradio/api/views/profiles.py b/savepointradio/api/views/profiles.py index ee2b039..2b4e568 100644 --- a/savepointradio/api/views/profiles.py +++ b/savepointradio/api/views/profiles.py @@ -5,12 +5,10 @@ from rest_framework.decorators import action from rest_framework.permissions import AllowAny from rest_framework.response import Response -from profiles.models import RadioProfile, Rating, SongRequest -from radio.models import Song +from profiles.models import RadioProfile, SongRequest from ..permissions import IsAdminOwnerOrReadOnly from ..serializers.profiles import (BasicProfileSerializer, FullProfileSerializer, - FavoriteSongSerializer, HistorySerializer, BasicProfileRatingsSerializer) from ..serializers.radio import BasicSongRetrieveSerializer @@ -47,19 +45,6 @@ class ProfileViewSet(viewsets.ModelViewSet): self.check_object_permissions(self.request, obj) return obj - @action(detail=True, permission_classes=[AllowAny]) - def ratings(self, request, pk=None): - profile = self.get_object() - ratings = profile.rating_profile.all().order_by('-created_date') - - page = self.paginate_queryset(ratings) - if page is not None: - serializer = BasicProfileRatingsSerializer(page, many=True) - return self.get_paginated_response(serializer.data) - - serializer = BasicProfileRatingsSerializer(ratings, many=True) - return Response(serializer.data) - @action(detail=True, permission_classes=[AllowAny]) def favorites(self, request, pk=None): profile = self.get_object() @@ -73,33 +58,18 @@ class ProfileViewSet(viewsets.ModelViewSet): serializer = BasicSongRetrieveSerializer(favorites, many=True) return Response(serializer.data) - def _favorite_change(self, request, remove=False): + @action(detail=True, permission_classes=[AllowAny]) + def ratings(self, request, pk=None): profile = self.get_object() - serializer = FavoriteSongSerializer(data=request.data) - if serializer.is_valid(): - song = Song.objects.get(pk=serializer.data['song']) - if remove: - profile.favorites.remove(song) - else: - profile.favorites.add(song) - profile.save() - message = 'Song {} favorites.'.format(('added to', - 'removed from')[remove]) - return Response({'detail': message}) - return Response(serializer.errors, - status=status.HTTP_400_BAD_REQUEST) + ratings = profile.rating_profile.all().order_by('-created_date') - @action(methods=['post'], - detail=True, - permission_classes=[IsAdminOwnerOrReadOnly]) - def favorite_add(self, request, pk=None): - return self._favorite_change(request) + page = self.paginate_queryset(ratings) + if page is not None: + serializer = BasicProfileRatingsSerializer(page, many=True) + return self.get_paginated_response(serializer.data) - @action(methods=['post'], - detail=True, - permission_classes=[IsAdminOwnerOrReadOnly]) - def favorite_remove(self, request, pk=None): - return self._favorite_change(request, remove=True) + serializer = BasicProfileRatingsSerializer(ratings, many=True) + return Response(serializer.data) class HistoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): diff --git a/savepointradio/api/views/radio.py b/savepointradio/api/views/radio.py index 158add9..9d07e7a 100644 --- a/savepointradio/api/views/radio.py +++ b/savepointradio/api/views/radio.py @@ -6,7 +6,8 @@ from rest_framework.response import Response from profiles.models import RadioProfile, Rating from radio.models import Album, Artist, Game, Song from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ -from ..serializers.profiles import (BasicSongRatingsSerializer, +from ..serializers.profiles import (BasicProfileSerializer, + BasicSongRatingsSerializer, RateSongSerializer) from ..serializers.radio import (AlbumSerializer, ArtistSerializer, GameSerializer, FullSongSerializer, @@ -72,6 +73,48 @@ class SongViewSet(viewsets.ModelViewSet): def artists_remove(self, request, pk=None): return self._artists_change(request, remove=True) + @action(detail=True, permission_classes=[AllowAny]) + def favorites(self, request, pk=None): + song = self.get_object() + profiles = song.song_favorites.all().order_by('user__name') + + page = self.paginate_queryset(profiles) + if page is not None: + serializer = BasicProfileSerializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = BasicProfileSerializer(profiles, many=True) + return Response(serializer.data) + + @action(methods=['post'], + detail=True, + permission_classes=[IsAuthenticatedAndNotDJ]) + def favorite(self, request, pk=None): + song = self.get_object() + profile = RadioProfile.objects.get(user=request.user) + if song not in profile.favorites.all(): + profile.favorites.add(song) + profile.save() + return Response({'detail': 'Song has been added to favorites.'}) + message = 'Song is already a favorite.' + return Response({'detail': message}, + status=status.HTTP_400_BAD_REQUEST) + + @action(methods=['post'], + detail=True, + permission_classes=[IsAuthenticatedAndNotDJ]) + def unfavorite(self, request, pk=None): + song = self.get_object() + profile = RadioProfile.objects.get(user=request.user) + if song in profile.favorites.all(): + profile.favorites.remove(song) + profile.save() + message = 'Song has been removed from favorites.' + return Response({'detail': message}) + message = 'Song is already not a favorite.' + return Response({'detail': message}, + status=status.HTTP_400_BAD_REQUEST) + @action(detail=True, permission_classes=[AllowAny]) def ratings(self, request, pk=None): song = self.get_object() @@ -89,28 +132,35 @@ class SongViewSet(viewsets.ModelViewSet): detail=True, permission_classes=[IsAuthenticatedAndNotDJ]) def rate(self, request, pk=None): - song = self.get_object() serializer = RateSongSerializer(data=request.data) if serializer.is_valid(): + song = self.get_object() profile = RadioProfile.objects.get(user=request.user) - - if serializer.data['rating'] == 0: - rating = song.rating_set.filter(profile=profile) - if rating: - rating.delete() - return Response({'detail': 'Rating deleted from song.'}) - message = 'Cannot delete nonexistant rating.' - return Response({'detail': message}, - status=status.HTTP_400_BAD_REQUEST) - else: + if 'value' in serializer.data: rating, created = Rating.objects.update_or_create( profile=profile, song=song, - defaults={'value': serializer.data['rating']} + defaults={'value': serializer.data['value']} ) - message = 'Rating {} song.'.format(('updated for', - 'created for')[created]) - return Response({'detail': message}) - else: - return Response(serializer.errors, + message = 'Rating {} song.'.format(('updated for', + 'created for')[created]) + return Response({'detail': message}) + message = 'Missing integer \'value\' for song rating.' + return Response({'detail': message}, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, + status=status.HTTP_400_BAD_REQUEST) + + @action(methods=['post'], + detail=True, + permission_classes=[IsAuthenticatedAndNotDJ]) + def unrate(self, request, pk=None): + song = self.get_object() + profile = RadioProfile.objects.get(user=request.user) + rating = song.rating_set.filter(profile=profile) + if rating: + rating.delete() + return Response({'detail': 'Rating deleted from song.'}) + message = 'Cannot delete nonexistant rating.' + return Response({'detail': message}, + status=status.HTTP_400_BAD_REQUEST)