From 139ac8d892f355528914c565c259dece5291bf7a Mon Sep 17 00:00:00 2001 From: Josh Washburne Date: Mon, 9 Apr 2018 12:11:15 -0400 Subject: [PATCH] Add song ratings functionality to API. --- savepointradio/api/serializers/profiles.py | 22 +++++++++- savepointradio/api/views/profiles.py | 16 ++++++- savepointradio/api/views/radio.py | 50 +++++++++++++++++++++- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/savepointradio/api/serializers/profiles.py b/savepointradio/api/serializers/profiles.py index 2324e8a..4d8387d 100644 --- a/savepointradio/api/serializers/profiles.py +++ b/savepointradio/api/serializers/profiles.py @@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model from rest_framework.serializers import (IntegerField, ModelSerializer, Serializer) -from profiles.models import RadioProfile, SongRequest +from profiles.models import RadioProfile, SongRequest, Rating from .radio import BasicSongRetrieveSerializer @@ -45,3 +45,23 @@ class HistorySerializer(ModelSerializer): class Meta: model = SongRequest fields = ('created_date', 'played_at', 'profile', 'song') + + +class BasicProfileRatingsSerializer(ModelSerializer): + song = BasicSongRetrieveSerializer() + + class Meta: + model = Rating + fields = ('created_date', 'song', 'value') + + +class BasicSongRatingsSerializer(ModelSerializer): + profile = BasicProfileSerializer() + + 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 f5c4a02..ee2b039 100644 --- a/savepointradio/api/views/profiles.py +++ b/savepointradio/api/views/profiles.py @@ -11,7 +11,8 @@ from ..permissions import IsAdminOwnerOrReadOnly from ..serializers.profiles import (BasicProfileSerializer, FullProfileSerializer, FavoriteSongSerializer, - HistorySerializer) + HistorySerializer, + BasicProfileRatingsSerializer) from ..serializers.radio import BasicSongRetrieveSerializer @@ -46,6 +47,19 @@ 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() diff --git a/savepointradio/api/views/radio.py b/savepointradio/api/views/radio.py index 8d60e90..158add9 100644 --- a/savepointradio/api/views/radio.py +++ b/savepointradio/api/views/radio.py @@ -1,10 +1,13 @@ from rest_framework import status, viewsets from rest_framework.decorators import action -from rest_framework.permissions import IsAdminUser +from rest_framework.permissions import AllowAny, IsAdminUser from rest_framework.response import Response +from profiles.models import RadioProfile, Rating from radio.models import Album, Artist, Game, Song -from ..permissions import IsAdminOrReadOnly +from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ +from ..serializers.profiles import (BasicSongRatingsSerializer, + RateSongSerializer) from ..serializers.radio import (AlbumSerializer, ArtistSerializer, GameSerializer, FullSongSerializer, SongArtistsListSerializer, @@ -68,3 +71,46 @@ class SongViewSet(viewsets.ModelViewSet): @action(methods=['post'], detail=True, permission_classes=[IsAdminUser]) def artists_remove(self, request, pk=None): return self._artists_change(request, remove=True) + + @action(detail=True, permission_classes=[AllowAny]) + def ratings(self, request, pk=None): + song = self.get_object() + ratings = song.rating_set.all().order_by('-created_date') + + page = self.paginate_queryset(ratings) + if page is not None: + serializer = BasicSongRatingsSerializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = BasicSongRatingsSerializer(ratings, many=True) + return Response(serializer.data) + + @action(methods=['post'], + detail=True, + permission_classes=[IsAuthenticatedAndNotDJ]) + def rate(self, request, pk=None): + song = self.get_object() + serializer = RateSongSerializer(data=request.data) + if serializer.is_valid(): + 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: + rating, created = Rating.objects.update_or_create( + profile=profile, + song=song, + defaults={'value': serializer.data['rating']} + ) + message = 'Rating {} song.'.format(('updated for', + 'created for')[created]) + return Response({'detail': message}) + else: + return Response(serializer.errors, + status=status.HTTP_400_BAD_REQUEST)