Add song ratings functionality to API.

This commit is contained in:
Josh Washburne 2018-04-09 12:11:15 -04:00
parent c186d2e997
commit 139ac8d892
3 changed files with 84 additions and 4 deletions

View file

@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model
from rest_framework.serializers import (IntegerField, ModelSerializer, from rest_framework.serializers import (IntegerField, ModelSerializer,
Serializer) Serializer)
from profiles.models import RadioProfile, SongRequest from profiles.models import RadioProfile, SongRequest, Rating
from .radio import BasicSongRetrieveSerializer from .radio import BasicSongRetrieveSerializer
@ -45,3 +45,23 @@ class HistorySerializer(ModelSerializer):
class Meta: class Meta:
model = SongRequest model = SongRequest
fields = ('created_date', 'played_at', 'profile', 'song') 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)

View file

@ -11,7 +11,8 @@ from ..permissions import IsAdminOwnerOrReadOnly
from ..serializers.profiles import (BasicProfileSerializer, from ..serializers.profiles import (BasicProfileSerializer,
FullProfileSerializer, FullProfileSerializer,
FavoriteSongSerializer, FavoriteSongSerializer,
HistorySerializer) HistorySerializer,
BasicProfileRatingsSerializer)
from ..serializers.radio import BasicSongRetrieveSerializer from ..serializers.radio import BasicSongRetrieveSerializer
@ -46,6 +47,19 @@ class ProfileViewSet(viewsets.ModelViewSet):
self.check_object_permissions(self.request, obj) self.check_object_permissions(self.request, obj)
return 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]) @action(detail=True, permission_classes=[AllowAny])
def favorites(self, request, pk=None): def favorites(self, request, pk=None):
profile = self.get_object() profile = self.get_object()

View file

@ -1,10 +1,13 @@
from rest_framework import status, viewsets from rest_framework import status, viewsets
from rest_framework.decorators import action 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 rest_framework.response import Response
from profiles.models import RadioProfile, Rating
from radio.models import Album, Artist, Game, Song 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, from ..serializers.radio import (AlbumSerializer, ArtistSerializer,
GameSerializer, FullSongSerializer, GameSerializer, FullSongSerializer,
SongArtistsListSerializer, SongArtistsListSerializer,
@ -68,3 +71,46 @@ class SongViewSet(viewsets.ModelViewSet):
@action(methods=['post'], detail=True, permission_classes=[IsAdminUser]) @action(methods=['post'], detail=True, permission_classes=[IsAdminUser])
def artists_remove(self, request, pk=None): def artists_remove(self, request, pk=None):
return self._artists_change(request, remove=True) 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)