Refactor rating functionality and move favoriting to Song API.

This commit is contained in:
Josh Washburne 2018-04-09 15:04:39 -04:00
parent 139ac8d892
commit 80b3eb2031
3 changed files with 82 additions and 62 deletions

View file

@ -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)

View file

@ -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):

View file

@ -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)