Stores now accessible through API.

This commit is contained in:
RecursiveGreen 2019-06-04 14:58:52 -04:00
parent 52ad3c8600
commit 58dddd2d0d
3 changed files with 87 additions and 8 deletions

View file

@ -1,4 +1,5 @@
from rest_framework.serializers import (DecimalField, IntegerField, ListField, from rest_framework.serializers import (BooleanField, DecimalField,
IntegerField, ListField,
ModelSerializer, Serializer, ModelSerializer, Serializer,
SerializerMethodField, SerializerMethodField,
StringRelatedField) StringRelatedField)
@ -48,7 +49,7 @@ class StoreSerializer(ModelSerializer):
def get_active(self, obj): def get_active(self, obj):
'''Checks to see if this store is active for a song.''' '''Checks to see if this store is active for a song.'''
if obj.active_for: if obj.active_for.all():
return True return True
return False return False
@ -139,4 +140,15 @@ class SongArtistsListSerializer(Serializer):
A serializer for adding or removing artists from a song based on A serializer for adding or removing artists from a song based on
the song's id number. the song's id number.
''' '''
# TODO: Probably should move to PrimaryKeyRelatedField.
artists = ListField(child=IntegerField(), min_length=1, max_length=10) artists = ListField(child=IntegerField(), min_length=1, max_length=10)
class SongStoresSerializer(Serializer):
'''
A serializer for adding or removing a data store from a song based on
the song's id number.
'''
# TODO: Probably should move to PrimaryKeyRelatedField.
store = IntegerField()
set_active = BooleanField(default=False)

View file

@ -4,8 +4,8 @@ from rest_framework.routers import DefaultRouter
from api.views.controls import JustPlayed, MakeRequest, NextRequest from api.views.controls import JustPlayed, MakeRequest, NextRequest
from api.views.profiles import HistoryViewSet, ProfileViewSet from api.views.profiles import HistoryViewSet, ProfileViewSet
from api.views.radio import (AlbumViewSet, ArtistViewSet, from api.views.radio import (AlbumViewSet, ArtistViewSet, GameViewSet,
GameViewSet, SongViewSet) StoreViewSet, SongViewSet)
class OptionalSlashRouter(DefaultRouter): class OptionalSlashRouter(DefaultRouter):
@ -28,6 +28,7 @@ router.register(r'profiles', ProfileViewSet, base_name='profile')
router.register(r'albums', AlbumViewSet, base_name='album') router.register(r'albums', AlbumViewSet, base_name='album')
router.register(r'artists', ArtistViewSet, base_name='artist') router.register(r'artists', ArtistViewSet, base_name='artist')
router.register(r'games', GameViewSet, base_name='game') router.register(r'games', GameViewSet, base_name='game')
router.register(r'stores', StoreViewSet, base_name='store')
router.register(r'songs', SongViewSet, base_name='song') router.register(r'songs', SongViewSet, base_name='song')
urlpatterns = [ urlpatterns = [

View file

@ -4,15 +4,17 @@ 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 profiles.models import RadioProfile, Rating
from radio.models import Album, Artist, Game, Song from radio.models import Album, Artist, Game, Song, Store
from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ from ..permissions import IsAdminOrReadOnly, IsAuthenticatedAndNotDJ
from ..serializers.profiles import (BasicProfileSerializer, from ..serializers.profiles import (BasicProfileSerializer,
BasicSongRatingsSerializer, BasicSongRatingsSerializer,
RateSongSerializer) RateSongSerializer)
from ..serializers.radio import (AlbumSerializer, ArtistSerializer, from ..serializers.radio import (AlbumSerializer, ArtistSerializer,
GameSerializer, SongSerializer, GameSerializer, StoreSerializer,
SongListSerializer, SongRetrieveSerializer, SongSerializer, SongListSerializer,
SongArtistsListSerializer) SongRetrieveSerializer,
SongArtistsListSerializer,
SongStoresSerializer)
class AlbumViewSet(viewsets.ModelViewSet): class AlbumViewSet(viewsets.ModelViewSet):
@ -63,6 +65,12 @@ class GameViewSet(viewsets.ModelViewSet):
return Game.music.available() return Game.music.available()
class StoreViewSet(viewsets.ModelViewSet):
queryset = Store.objects.all()
permission_classes = [IsAdminUser]
serializer_class = StoreSerializer
class SongViewSet(viewsets.ModelViewSet): class SongViewSet(viewsets.ModelViewSet):
permission_classes = [IsAdminOrReadOnly] permission_classes = [IsAdminOrReadOnly]
@ -94,12 +102,18 @@ class SongViewSet(viewsets.ModelViewSet):
serializer = SongArtistsListSerializer(data=request.data) serializer = SongArtistsListSerializer(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
artists = Artist.objects.filter(pk__in=serializer.data['artists']) artists = Artist.objects.filter(pk__in=serializer.data['artists'])
for artist in artists: for artist in artists:
if remove: if remove:
song.artists.remove(artist) song.artists.remove(artist)
else: else:
song.artists.add(artist) song.artists.add(artist)
song.save() song.save()
if song.artists.count() == 0:
song.disable('No artists specified for song.')
message = 'Artists {} song.'.format(('added to', message = 'Artists {} song.'.format(('added to',
'removed from')[remove]) 'removed from')[remove])
return Response({'detail': message}) return Response({'detail': message})
@ -115,6 +129,58 @@ class SongViewSet(viewsets.ModelViewSet):
'''Removes an artist from a song.''' '''Removes an artist from a song.'''
return self._artists_change(request, remove=True) return self._artists_change(request, remove=True)
def _store_change(self, request, remove=False):
song = self.get_object()
serializer = SongStoresSerializer(data=request.data)
if serializer.is_valid():
try:
store = Store.objects.get(pk=serializer.data['store'])
except Store.DoesNotExist:
return Response({'detail': 'Store does not exist.'},
status=status.HTTP_400_BAD_REQUEST)
if remove:
song.stores.remove(store)
else:
song.stores.add(store)
if serializer.data['set_active'] and not remove:
song.active_store = store
song.save()
if song.stores.count() == 0:
song.disable('No stores specified for song.')
message = 'Store {} song.'.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=[IsAdminUser])
def store_add(self, request, pk=None):
'''Adds a data store to a song.'''
return self._store_change(request)
@action(methods=['post'], detail=True, permission_classes=[IsAdminUser])
def store_remove(self, request, pk=None):
'''Removes a data store from a song.'''
return self._store_change(request, remove=True)
@action(detail=True, permission_classes=[IsAdminUser])
def stores(self, request, pk=None):
'''Get a list of data stores associate with this song.'''
song = self.get_object()
stores = song.stores.all().order_by('-created_date')
page = self.paginate_queryset(stores)
if page is not None:
serializer = StoreSerializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = StoreSerializer(stores, 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):
'''Get a list of users who added this song to their favorites list.''' '''Get a list of users who added this song to their favorites list.'''