From a2283ed6f1ad6bc8fe38e9c930f33e7a7efe02bb Mon Sep 17 00:00:00 2001 From: Marharyta Zazulia Date: Sat, 7 Dec 2024 15:15:40 -0300 Subject: [PATCH] Solution --- .gitignore | 1 + cinema/models.py | 16 +++++--- cinema/serializers.py | 91 +++++++++++++++++++++++++++++++++++++++++- cinema/urls.py | 27 ++++++++++++- cinema/views.py | 64 ++++++++++++++++++++++++++++- cinema_service/urls.py | 6 ++- 6 files changed, 194 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index b26d6116..b9b230d8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ venv/ .pytest_cache/ **__pycache__/ +db.sqlite3 diff --git a/cinema/models.py b/cinema/models.py index c42d2a3d..4af55091 100644 --- a/cinema/models.py +++ b/cinema/models.py @@ -27,7 +27,11 @@ class Actor(models.Model): first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) - def __str__(self): + @property + def full_name(self) -> str: + return self.__str__() + + def __str__(self) -> str: return self.first_name + " " + self.last_name @@ -41,7 +45,7 @@ class Movie(models.Model): class Meta: ordering = ["title"] - def __str__(self): + def __str__(self) -> str: return self.title @@ -53,7 +57,7 @@ class MovieSession(models.Model): class Meta: ordering = ["-show_time"] - def __str__(self): + def __str__(self) -> str: return self.movie.title + " " + str(self.show_time) @@ -63,7 +67,7 @@ class Order(models.Model): settings.AUTH_USER_MODEL, on_delete=models.CASCADE ) - def __str__(self): + def __str__(self) -> str: return str(self.created_at) class Meta: @@ -80,7 +84,7 @@ class Ticket(models.Model): row = models.IntegerField() seat = models.IntegerField() - def clean(self): + def clean(self) -> None: for ticket_attr_value, ticket_attr_name, cinema_hall_attr_name in [ (self.row, "row", "count_rows"), (self.seat, "seat", "count_seats_in_row"), @@ -98,7 +102,7 @@ def clean(self): } ) - def __str__(self): + def __str__(self) -> str: return ( f"{str(self.movie_session)} (row: {self.row}, seat: {self.seat})" ) diff --git a/cinema/serializers.py b/cinema/serializers.py index 612ca7e2..47e63227 100644 --- a/cinema/serializers.py +++ b/cinema/serializers.py @@ -1 +1,90 @@ -# write serializers here +from rest_framework import serializers + +from cinema.models import Genre, Actor, CinemaHall, Movie, MovieSession + + +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 CinemaHallSerializer(serializers.ModelSerializer): + capacity = serializers.ReadOnlyField() + + class Meta: + model = CinemaHall + fields = ("id", "name", "rows", "seats_in_row", "capacity") + + +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(serializers.ModelSerializer): + movie_title = serializers.CharField(source="movie.title", read_only=True) + cinema_hall_name = serializers.CharField( + source="cinema_hall.name", + read_only=True + ) + cinema_hall_capacity = serializers.IntegerField( + source="cinema_hall.capacity", + read_only=True + ) + + class Meta: + model = MovieSession + fields = ( + "id", + "show_time", + "movie_title", + "cinema_hall_name", + "cinema_hall_capacity", + ) + + +class MovieSessionRetrieveSerializer(serializers.ModelSerializer): + movie = MovieListSerializer(read_only=True) + cinema_hall = CinemaHallSerializer(read_only=True) + + class Meta: + model = MovieSession + fields = ("id", "show_time", "movie", "cinema_hall", ) diff --git a/cinema/urls.py b/cinema/urls.py index 420f8e8c..5360ffc3 100644 --- a/cinema/urls.py +++ b/cinema/urls.py @@ -1 +1,26 @@ -# write urls here +from django.urls import path, include +from rest_framework import routers + +from cinema.views import ( + GenreViewSet, + ActorViewSet, + CinemaHallViewSet, + MovieViewSet, + MovieSessionViewSet, +) + +router = routers.DefaultRouter() + +router.register("genres", GenreViewSet) +router.register("actors", ActorViewSet) +router.register("cinema_halls", CinemaHallViewSet) +router.register("movies", MovieViewSet) +router.register("movie_sessions", MovieSessionViewSet) + + +app_name = "cinema" + + +urlpatterns = [ + path("", include(router.urls)), +] diff --git a/cinema/views.py b/cinema/views.py index ae87bfde..50a56478 100644 --- a/cinema/views.py +++ b/cinema/views.py @@ -1 +1,63 @@ -# write views here +from rest_framework import viewsets + +from cinema.models import Genre, Actor, CinemaHall, Movie, MovieSession +from cinema.serializers import ( + GenreSerializer, + ActorSerializer, + CinemaHallSerializer, + MovieSerializer, + MovieSessionSerializer, + MovieListSerializer, + MovieRetrieveSerializer, + MovieSessionListSerializer, + MovieSessionRetrieveSerializer, +) + + +class GenreViewSet(viewsets.ModelViewSet): + queryset = Genre.objects.all() + serializer_class = GenreSerializer + + +class ActorViewSet(viewsets.ModelViewSet): + queryset = Actor.objects.all() + serializer_class = ActorSerializer + + +class CinemaHallViewSet(viewsets.ModelViewSet): + queryset = CinemaHall.objects.all() + serializer_class = CinemaHallSerializer + + +class MovieViewSet(viewsets.ModelViewSet): + queryset = Movie.objects.all() + + def get_serializer_class(self): + if self.action == "list": + return MovieListSerializer + if self.action == "retrieve": + return MovieRetrieveSerializer + return MovieSerializer + + def get_queryset(self): + queryset = self.queryset + if self.action in ("list", "retrieve", ): + return queryset.prefetch_related("genres", "actors") + return queryset + + +class MovieSessionViewSet(viewsets.ModelViewSet): + queryset = MovieSession.objects.all() + + def get_serializer_class(self): + if self.action == "list": + return MovieSessionListSerializer + if self.action == "retrieve": + return MovieSessionRetrieveSerializer + return MovieSessionSerializer + + def get_queryset(self): + queryset = self.queryset + if self.action in ("list", "retrieve", ): + return queryset.select_related("movie", "cinema_hall") + return queryset diff --git a/cinema_service/urls.py b/cinema_service/urls.py index 083932c6..bfc0353e 100644 --- a/cinema_service/urls.py +++ b/cinema_service/urls.py @@ -1,6 +1,8 @@ +from debug_toolbar.toolbar import debug_toolbar_urls 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"), name="cinema"), +] + debug_toolbar_urls()