diff --git a/cinema/models.py b/cinema/models.py index c42d2a3d..56922020 100644 --- a/cinema/models.py +++ b/cinema/models.py @@ -27,6 +27,10 @@ class Actor(models.Model): first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) + @property + def full_name(self): + return f"{self.first_name} {self.last_name}" + def __str__(self): return self.first_name + " " + self.last_name diff --git a/cinema/serializers.py b/cinema/serializers.py index 612ca7e2..4d832293 100644 --- a/cinema/serializers.py +++ b/cinema/serializers.py @@ -1 +1,103 @@ -# write serializers here +from rest_framework import serializers + +from cinema.models import ( + CinemaHall, + Genre, + Actor, + Movie, + MovieSession +) + + +class CinemaHallSerializer(serializers.ModelSerializer): + capacity = serializers.IntegerField(read_only=True) + + class Meta: + model = CinemaHall + fields = ( + "id", + "name", + "rows", + "seats_in_row", + "capacity" + ) + + def get_capacity(self, obj): + return obj.rows * obj.seats_in_row + + +class GenreSerializer(serializers.ModelSerializer): + class Meta: + model = Genre + fields = ( + "id", + "name" + ) + + +class ActorSerializer(serializers.ModelSerializer): + class Meta: + model = Actor + fields = ( + "id", + "first_name", + "last_name", + "full_name" + ) + + +class MovieSerializer(serializers.ModelSerializer): + class Meta: + model = Movie + fields = ("id", "title", "description", "duration", "genres", "actors") + + +class MovieListSerializer(MovieSerializer): + genres = serializers.SlugRelatedField( + many=True, + read_only=True, + slug_field="name" + ) + actors = serializers.SlugRelatedField( + many=True, + read_only=True, + slug_field="full_name" + ) + + +class MovieRetrieveSerializer(MovieSerializer): + genres = GenreSerializer(many=True, read_only=True) + actors = ActorSerializer(many=True, read_only=True) + + +class MovieSessionSerializer(serializers.ModelSerializer): + class Meta: + model = MovieSession + fields = "__all__" + + +class MovieSessionListSerializer(MovieSessionSerializer): + movie_title = serializers.CharField( + source="movie.title" + ) + cinema_hall_name = serializers.CharField( + source="cinema_hall.name" + ) + cinema_hall_capacity = serializers.IntegerField( + source="cinema_hall.capacity" + ) + + class Meta: + model = MovieSession + fields = ( + "id", + "show_time", + "movie_title", + "cinema_hall_name", + "cinema_hall_capacity" + ) + + +class MovieSessionRetrieveSerializer(MovieSessionSerializer): + movie = MovieListSerializer(many=False, read_only=True) + cinema_hall = CinemaHallSerializer(many=False, read_only=True) diff --git a/cinema/urls.py b/cinema/urls.py index 420f8e8c..c73b49c9 100644 --- a/cinema/urls.py +++ b/cinema/urls.py @@ -1 +1,25 @@ -# write urls here +from django.urls import path, include + +from rest_framework.routers import DefaultRouter + +from cinema.views import ( + CinemaHallViewSet, + GenreViewSet, + ActorViewSet, + MovieViewSet, + MovieSessionViewSet +) + +app_name = "cinema" + +router = DefaultRouter() + +router.register("cinema_halls", CinemaHallViewSet) +router.register("genres", GenreViewSet) +router.register("actors", ActorViewSet) +router.register("movies", MovieViewSet) +router.register("movie_sessions", MovieSessionViewSet) + +urlpatterns = [ + path("", include(router.urls)), +] diff --git a/cinema/views.py b/cinema/views.py index ae87bfde..10d1437c 100644 --- a/cinema/views.py +++ b/cinema/views.py @@ -1 +1,63 @@ -# write views here +from rest_framework.viewsets import ModelViewSet +from cinema.models import Genre, Actor, CinemaHall, Movie, MovieSession +from cinema.serializers import ( + GenreSerializer, + ActorSerializer, + CinemaHallSerializer, + MovieListSerializer, + MovieSerializer, + MovieRetrieveSerializer, + MovieSessionListSerializer, + MovieSessionRetrieveSerializer, MovieSessionSerializer, + +) + + +class GenreViewSet(ModelViewSet): + queryset = Genre.objects.all() + serializer_class = GenreSerializer + + +class ActorViewSet(ModelViewSet): + queryset = Actor.objects.all() + serializer_class = ActorSerializer + + +class CinemaHallViewSet(ModelViewSet): + queryset = CinemaHall.objects.all() + serializer_class = CinemaHallSerializer + + +class MovieViewSet(ModelViewSet): + queryset = Movie.objects.all() + + def get_queryset(self): + queryset = self.queryset + if self.action in ("list", "retrieve"): + queryset = queryset.prefetch_related("genres", "actors") + return queryset + + def get_serializer_class(self): + if self.action == "list": + return MovieListSerializer + if self.action == "retrieve": + return MovieRetrieveSerializer + return MovieSerializer + + +class MovieSessionViewSet(ModelViewSet): + queryset = MovieSession.objects.all() + + def get_queryset(self): + queryset = self.queryset + if self.action in ("list", "retrieve"): + return queryset.select_related("movie", "cinema_hall") + + return queryset + + def get_serializer_class(self): + if self.action == "list": + return MovieSessionListSerializer + if self.action == "retrieve": + return MovieSessionRetrieveSerializer + return MovieSessionSerializer diff --git a/cinema_service/urls.py b/cinema_service/urls.py index 083932c6..229767ed 100644 --- a/cinema_service/urls.py +++ b/cinema_service/urls.py @@ -1,6 +1,7 @@ from django.contrib import admin -from django.urls import path +from django.urls import path, include urlpatterns = [ path("admin/", admin.site.urls), + path("api/cinema/", include("cinema.urls", namespace="cinema")), ]