from django.shortcuts import get_object_or_404 from rest_framework import mixins, status, viewsets 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 ..permissions import IsAdminOwnerOrReadOnly from ..serializers.profiles import (BasicProfileSerializer, FullProfileSerializer, FavoriteSongSerializer, HistorySerializer) from ..serializers.radio import BasicSongRetrieveSerializer class ProfileViewSet(viewsets.ModelViewSet): permission_classes = [IsAdminOwnerOrReadOnly] queryset = RadioProfile.objects.all() serializer_class = BasicProfileSerializer def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.is_owner = False def get_serializer_class(self): ''' Choose a different serializer based on if the requesting user is an admin or is the same person as the profile requested. ''' if self.request.user.is_staff or self.is_owner: return FullProfileSerializer return BasicProfileSerializer def get_object(self): ''' Grab the object as normal, but let us know if the requesting user is the owner. ''' obj = get_object_or_404(self.get_queryset(), **self.kwargs) if self.request.user.pk == obj.user.pk: self.is_owner = True else: self.is_owner = False self.check_object_permissions(self.request, obj) return obj @action(detail=True, permission_classes=[AllowAny]) def favorites(self, request, pk=None): profile = self.get_object() favorites = profile.favorites.all().order_by('sorted_title') page = self.paginate_queryset(favorites) if page is not None: serializer = BasicSongRetrieveSerializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = BasicSongRetrieveSerializer(favorites, many=True) return Response(serializer.data) def _favorite_change(self, request, remove=False): 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) @action(methods=['post'], detail=True, permission_classes=[IsAdminOwnerOrReadOnly]) def favorite_add(self, request, pk=None): return self._favorite_change(request) @action(methods=['post'], detail=True, permission_classes=[IsAdminOwnerOrReadOnly]) def favorite_remove(self, request, pk=None): return self._favorite_change(request, remove=True) class HistoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): permission_classes = [AllowAny] queryset = SongRequest.objects.all() serializer_class = HistorySerializer