first backend frontend split

with docker compose file
nextjs something something
also includes migrations
This commit is contained in:
2025-06-20 14:06:00 +02:00
parent e7cc031588
commit dfc242084e
138 changed files with 1592 additions and 13 deletions
+24
View File
@@ -0,0 +1,24 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from playlist.models import Album
from playlist.serializers import AlbumSerializer
class AlbumListView(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
albums = Album.objects.all()
serializer = AlbumSerializer(albums, many=True, context={'request': request})
return Response(serializer.data)
class AlbumDetailView(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request, id):
album = Album.objects.get(pk=id)
serializer = AlbumSerializer(album, context={'request': request})
return Response(serializer.data)
+17
View File
@@ -0,0 +1,17 @@
from itertools import permutations
from rest_framework.views import APIView
from rest_framework.response import Response
from playlist.models import Artist
from playlist.serializers import ArtistSerializer
class ArtistListView(APIView):
def get(self, request):
artists = Artist.objects.all()
serializer = ArtistSerializer(artists, many=True, context={'request': request})
return Response(serializer.data)
class ArtistDetailView(APIView):
def get(self, request, id):
artist = Artist.objects.get(pk=id)
serializer = ArtistSerializer(artist, context={'request': request})
return Response(serializer.data)
+32
View File
@@ -0,0 +1,32 @@
from pickle import BUILD
from playlist import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from playlist.serializers import ProfileSerializer, ProfileUpdateSerializer, BackgroundSerializer
from playlist.models import Profile, Background
class ProfileDetailView(APIView):
def get(self, request, id):
profile = Profile.objects.get(pk=id)
serializer = ProfileSerializer(profile)
return Response(serializer.data)
def put(self, request, id):
profile = Profile.objects.get(pk=id)
serializer = ProfileUpdateSerializer(profile, data=request.data)
serializer.is_valid()
serializer.save()
return Response(serializer.data)
#return Response()
class BackgroundListView(APIView):
def get(self, request):
backgrounds = Background.objects.all()
serializer = BackgroundSerializer(backgrounds, many=True)
return Response(serializer.data)
class BackgroundDetailView(APIView):
def get(self, request, id):
background = Background.objects.get(pk=id)
serializer = BackgroundSerializer(background)
return Response(serializer.data)
+14
View File
@@ -0,0 +1,14 @@
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.reverse import reverse
@api_view(['GET'])
@permission_classes([])
def api_root(request, format=None):
return Response({
'tracks': reverse('api-tracks', request=request, format=format),
'artists': reverse('api-artists', request=request, format=format),
'users': reverse('api-users', request=request, format=format),
'albums': reverse('api-albums', request=request, format=format),
'votes': reverse('api-votes', request=request, format=format),
})
+34
View File
@@ -0,0 +1,34 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from playlist.models import Track, Profile
from playlist.serializers import TrackSerializer
from playlist.spotify import spt
from playlist.tasks import get_banter, get_and_dither_image
class TrackListView(APIView):
def get(self, request):
tracks = Track.objects.all()
serializer = TrackSerializer(tracks, many=True, context={'request': request})
return Response(serializer.data)
def post(self, request):
(profile, _) = Profile.objects.get_or_create(user=request.user)
(can_nom, reason) = profile.can_nominate
if not can_nom:
return Response({'error': reason}, status=403)
(track, message) = Track.objects.create_from_spotify(request.data['spotify_link'], profile)
serializer = TrackSerializer(track, context={'request': request})
return Response(serializer.data)
def delete(self, request):
if request.user.is_superuser:
Track.objects.all().delete()
return Response(status=204)
else:
return Response({'error': 'Only superusers can delete all tracks'}, status=403)
class TrackDetailView(APIView):
def get(self, request, id):
track = Track.objects.get(pk=id)
serializer = TrackSerializer(track, context={'request': request})
return Response(serializer.data)
+16
View File
@@ -0,0 +1,16 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth.models import User
from playlist.serializers import UserSerializer
class UserListView(APIView):
def get(self, request):
users = User.objects.all()
serializer = UserSerializer(users, many=True, context={'request': request})
return Response(serializer.data)
class UserDetailView(APIView):
def get(self, request, id):
user = User.objects.get(pk=id)
serializer = UserSerializer(user, context={'request': request})
return Response(serializer.data)
+48
View File
@@ -0,0 +1,48 @@
from django.db import IntegrityError
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from playlist.models import Vote, Profile
from playlist.serializers import VoteSerializer, VoteSaveSerializer
class VoteListView(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request, user_id = None):
if user_id:
votes = Vote.objects.filter(user_id=user_id)
else:
votes = Vote.objects.all()
serializer = VoteSerializer(votes, many=True, context={'request': request})
return Response(serializer.data)
def post(self, request):
(profile,_) = Profile.objects.get_or_create(user=request.user)
if not profile.can_vote:
return Response({'error': 'User cannot vote'}, status=403)
serializer = VoteSaveSerializer(data=request.data, context={'request': request})
if serializer.is_valid():
try:
serializer.save(user=request.user)
return Response(serializer.data, status=201)
except IntegrityError:
return Response({'error': 'Duplicate vote'}, status=400)
return Response(serializer.errors, status=400)
def delete(self, request):
if request.user.is_superuser:
Vote.objects.all().delete()
return Response(status=204)
else:
return Response(status=403)
class VoteDetailView(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request, id):
vote = Vote.objects.get(pk=id)
serializer = VoteSerializer(vote, context={'request': request})
return Response(serializer.data)