feat: add booking REST API

This commit is contained in:
2026-04-29 09:45:44 +02:00
parent 441d73d473
commit 89cf08647c
8 changed files with 429 additions and 1 deletions

View File

@@ -0,0 +1,55 @@
from rest_framework import serializers
class PublicShowListSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField()
slug = serializers.SlugField()
summary = serializers.CharField()
poster_image = serializers.URLField(allow_blank=True)
class PublicVenueSummarySerializer(serializers.Serializer):
name = serializers.CharField()
city = serializers.CharField()
class PublicVenueDetailSerializer(PublicVenueSummarySerializer):
address = serializers.CharField()
class PublicShowSummarySerializer(serializers.Serializer):
title = serializers.CharField()
slug = serializers.SlugField()
summary = serializers.CharField()
class PublicPerformanceListSerializer(serializers.Serializer):
id = serializers.IntegerField()
show = PublicShowSummarySerializer()
venue = PublicVenueSummarySerializer()
starts_at = serializers.DateTimeField()
booking_enabled = serializers.BooleanField(source="is_booking_enabled")
available_seats = serializers.IntegerField()
class PublicShowPerformanceSerializer(serializers.Serializer):
id = serializers.IntegerField()
starts_at = serializers.DateTimeField()
venue = PublicVenueSummarySerializer()
booking_enabled = serializers.BooleanField(source="is_booking_enabled")
available_seats = serializers.IntegerField()
class PublicShowDetailSerializer(PublicShowListSerializer):
description = serializers.CharField()
performances = PublicShowPerformanceSerializer(many=True, source="public_performances")
class PublicPerformanceDetailSerializer(serializers.Serializer):
id = serializers.IntegerField()
show = PublicShowSummarySerializer()
venue = PublicVenueDetailSerializer()
starts_at = serializers.DateTimeField()
booking_enabled = serializers.BooleanField(source="is_booking_enabled")
available_seats = serializers.IntegerField()

11
backend/shows/urls.py Normal file
View File

@@ -0,0 +1,11 @@
from django.urls import path
from . import views
urlpatterns = [
path("shows/", views.show_list, name="api-show-list"),
path("shows/<slug:slug>/", views.show_detail, name="api-show-detail"),
path("performances/", views.performance_list, name="api-performance-list"),
path("performances/<int:pk>/", views.performance_detail, name="api-performance-detail"),
]

65
backend/shows/views.py Normal file
View File

@@ -0,0 +1,65 @@
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.dateparse import parse_datetime
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Performance, Show
from .serializers import (
PublicPerformanceDetailSerializer,
PublicPerformanceListSerializer,
PublicShowDetailSerializer,
PublicShowListSerializer,
)
def public_performance_queryset():
return Performance.objects.select_related("show", "venue").filter(
show__is_published=True,
starts_at__gte=timezone.now(),
)
@api_view(["GET"])
def show_list(request):
shows = Show.objects.filter(is_published=True).order_by("title")
serializer = PublicShowListSerializer(shows, many=True)
return Response({"results": serializer.data})
@api_view(["GET"])
def show_detail(request, slug):
show = get_object_or_404(Show, slug=slug, is_published=True)
show.public_performances = public_performance_queryset().filter(show=show)
serializer = PublicShowDetailSerializer(show)
return Response(serializer.data)
@api_view(["GET"])
def performance_list(request):
performances = public_performance_queryset()
show_slug = request.query_params.get("show")
if show_slug:
performances = performances.filter(show__slug=show_slug)
from_value = request.query_params.get("from")
if from_value:
starts_from = parse_datetime(from_value)
if starts_from is None:
return Response(
{"from": ["Enter a valid ISO 8601 date/time."]},
status=status.HTTP_400_BAD_REQUEST,
)
performances = performances.filter(starts_at__gte=starts_from)
serializer = PublicPerformanceListSerializer(performances.order_by("starts_at"), many=True)
return Response({"results": serializer.data})
@api_view(["GET"])
def performance_detail(request, pk):
performance = get_object_or_404(public_performance_queryset(), pk=pk)
serializer = PublicPerformanceDetailSerializer(performance)
return Response(serializer.data)