From 5be6bbd541337734852f3b14e80e99b9d7b1c747 Mon Sep 17 00:00:00 2001 From: Vladimir Dolhyi Date: Wed, 4 Dec 2024 23:44:39 +0200 Subject: [PATCH] Solution --- .flake8 | 2 +- .gitignore | 1 + cinema/models.py | 4 +++ cinema/serializers.py | 72 +++++++++++++++++++++++++++++++++++++++++- cinema/urls.py | 22 ++++++++++++- cinema/views.py | 64 ++++++++++++++++++++++++++++++++++++- cinema_service/urls.py | 3 +- requirements.txt | 2 +- 8 files changed, 164 insertions(+), 6 deletions(-) diff --git a/.flake8 b/.flake8 index b5381af3..e8114cc1 100644 --- a/.flake8 +++ b/.flake8 @@ -7,4 +7,4 @@ select = B,C,E,F,W,T4,B9,Q0,N8,VNE exclude = **migrations venv - tests \ No newline at end of file + tests 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..3fe16827 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) -> str: + 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..c10ead14 100644 --- a/cinema/serializers.py +++ b/cinema/serializers.py @@ -1 +1,71 @@ -# write serializers here +from rest_framework import serializers + +from cinema.models import CinemaHall, Genre, Actor, Movie, MovieSession + + +class CinemaHallSerializer(serializers.ModelSerializer): + + class Meta: + model = CinemaHall + fields = ["id", "name", "rows", "seats_in_row", "capacity"] + + +class GenreSerializer(serializers.ModelSerializer): + + class Meta: + model = Genre + fields = "__all__" + + +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 = "__all__" + + +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(MovieSessionSerializer): + movie = MovieListSerializer() + cinema_hall = CinemaHallSerializer() diff --git a/cinema/urls.py b/cinema/urls.py index 420f8e8c..0e490472 100644 --- a/cinema/urls.py +++ b/cinema/urls.py @@ -1 +1,21 @@ -# write urls here +from django.urls import include, path +from rest_framework import routers + +from cinema.views import ( + CinemaHallViewSet, + GenreViewSet, + MovieViewSet, + ActorViewSet, + MovieSessionViewSet +) + +app_name = "cinema" + +router = routers.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..42adbf82 100644 --- a/cinema/views.py +++ b/cinema/views.py @@ -1 +1,63 @@ -# write views here +from rest_framework import viewsets + +from cinema.models import Movie, CinemaHall, Genre, Actor, MovieSession +from cinema.serializers import ( + MovieSerializer, + CinemaHallSerializer, + GenreSerializer, + ActorSerializer, + MovieSessionSerializer, + MovieSessionListSerializer, + MovieListSerializer, + MovieRetrieveSerializer, + MovieSessionRetrieveSerializer +) + + +class CinemaHallViewSet(viewsets.ModelViewSet): + queryset = CinemaHall.objects.all() + serializer_class = CinemaHallSerializer + + +class GenreViewSet(viewsets.ModelViewSet): + queryset = Genre.objects.all() + serializer_class = GenreSerializer + + +class ActorViewSet(viewsets.ModelViewSet): + queryset = Actor.objects.all() + serializer_class = ActorSerializer + + +class MovieViewSet(viewsets.ModelViewSet): + queryset = Movie.objects.all() + + def get_serializer_class(self): + if self.action == "list": + return MovieListSerializer + elif 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 + elif 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..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")), ] diff --git a/requirements.txt b/requirements.txt index 108897e9..4372e38a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ djangorestframework==3.13.1 flake8==5.0.4 flake8-quotes==3.3.1 flake8-variables-names==0.0.5 -pep8-naming==0.13.2 \ No newline at end of file +pep8-naming==0.13.2