From bc127a0182afe4d99e1f139e56aca196902b3ee9 Mon Sep 17 00:00:00 2001 From: Anastasiia Karpenko Date: Wed, 11 Dec 2024 17:59:23 +0200 Subject: [PATCH 1/5] Solution --- .gitignore | 1 + cinema/serializers.py | 66 +++++++++++++++++++++++++++++++++++++- cinema/urls.py | 18 ++++++++++- cinema/views.py | 64 +++++++++++++++++++++++++++++++++++- cinema_service/settings.py | 13 ++++++-- cinema_service/urls.py | 6 ++-- requirements.txt | 10 +++++- 7 files changed, 169 insertions(+), 9 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/serializers.py b/cinema/serializers.py index 612ca7e2..6a8a171c 100644 --- a/cinema/serializers.py +++ b/cinema/serializers.py @@ -1 +1,65 @@ -# 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): + full_name = serializers.SerializerMethodField() + + class Meta: + model = Actor + fields = ("id", "first_name", "last_name", "full_name") + + def get_full_name(self, obj): + return f"{obj.first_name} {obj.last_name}" + + +class MovieSerializer(serializers.ModelSerializer): + class Meta: + model = Movie + fields = ("id", "title", "description", "duration", "genres", "actors") + + +class MovieListSerializer(MovieSerializer): + actors = serializers.StringRelatedField(many=True) + genres = serializers.StringRelatedField(many=True) + + +class MovieRetrieveSerializer(MovieSerializer): + genres = GenreSerializer(many=True) + actors = ActorSerializer(many=True) + + +class MovieSessionSerializer(serializers.ModelSerializer): + class Meta: + model = MovieSession + fields = ("id", "show_time", "movie", "cinema_hall") + + +class MovieSessionListSerializer(serializers.ModelSerializer): + 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() + cinema_hall = CinemaHallSerializer() diff --git a/cinema/urls.py b/cinema/urls.py index 420f8e8c..bdf4fd27 100644 --- a/cinema/urls.py +++ b/cinema/urls.py @@ -1 +1,17 @@ -# write urls here +from django.urls import path, include +from rest_framework import routers + +from cinema import views + +router = routers.DefaultRouter() +router.register("cinema_halls", views.CinemaHallViewSet) +router.register("genres", views.GenreViewSet) +router.register("actors", views.ActorViewSet) +router.register("movies", views.MovieViewSet) +router.register("movie_sessions", views.MovieSessionViewSet) + +urlpatterns = [ + path("", include(router.urls)), +] + +app_name = "cinema" diff --git a/cinema/views.py b/cinema/views.py index ae87bfde..677d00e8 100644 --- a/cinema/views.py +++ b/cinema/views.py @@ -1 +1,63 @@ -# write views here +from rest_framework import viewsets + +from cinema.models import CinemaHall, Genre, Actor, Movie, MovieSession +from cinema.serializers import (CinemaHallSerializer, + GenreSerializer, + ActorSerializer, + MovieSerializer, + MovieSessionSerializer, + MovieListSerializer, + MovieRetrieveSerializer, + MovieSessionListSerializer, + 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().prefetch_related("genres", "actors") + serializer_class = MovieSerializer + + 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() + serializer_class = MovieSessionSerializer + + 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/settings.py b/cinema_service/settings.py index 4b981921..3ba9c3b6 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -12,6 +12,8 @@ from pathlib import Path +from decouple import config + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -20,9 +22,7 @@ # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = ( - "django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" -) +SECRET_KEY = config("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -42,6 +42,7 @@ "rest_framework", "cinema", "user", + "debug_toolbar", ] MIDDLEWARE = [ @@ -52,6 +53,7 @@ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", + "debug_toolbar.middleware.DebugToolbarMiddleware", ] ROOT_URLCONF = "cinema_service.urls" @@ -131,3 +133,8 @@ # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + + +INTERNAL_IPS = [ + "127.0.0.1", +] \ No newline at end of file diff --git a/cinema_service/urls.py b/cinema_service/urls.py index 083932c6..e8483a8c 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", namespace="cinema")), +] + debug_toolbar_urls() diff --git a/requirements.txt b/requirements.txt index 108897e9..2498a21d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,14 @@ +asgiref==3.8.1 Django==4.0.4 +django-debug-toolbar==4.4.6 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 +mccabe==0.7.0 +pep8-naming==0.13.2 +pycodestyle==2.9.1 +pyflakes==2.5.0 +python-decouple==3.8 +pytz==2024.2 +sqlparse==0.5.3 From 5b49118cf57ebbad9901e73137280d5424484278 Mon Sep 17 00:00:00 2001 From: Anastasiia Karpenko Date: Wed, 11 Dec 2024 18:01:53 +0200 Subject: [PATCH 2/5] change some requirements --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2498a21d..9288b955 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ asgiref==3.8.1 Django==4.0.4 -django-debug-toolbar==4.4.6 +django-debug-toolbar==3.2.1 djangorestframework==3.13.1 flake8==5.0.4 flake8-quotes==3.3.1 From d2fb15947438291d23832cea0b722e677e23571a Mon Sep 17 00:00:00 2001 From: Anastasiia Karpenko Date: Wed, 11 Dec 2024 18:05:55 +0200 Subject: [PATCH 3/5] code refactore --- cinema/serializers.py | 5 +++-- cinema_service/settings.py | 4 ++-- cinema_service/urls.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cinema/serializers.py b/cinema/serializers.py index 6a8a171c..e67d8414 100644 --- a/cinema/serializers.py +++ b/cinema/serializers.py @@ -51,8 +51,9 @@ class Meta: class MovieSessionListSerializer(serializers.ModelSerializer): 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")) + cinema_hall_capacity = (serializers.IntegerField( + source="cinema_hall.capacity") + ) class Meta: model = MovieSession diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 3ba9c3b6..92971ae4 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -25,7 +25,7 @@ SECRET_KEY = config("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = False ALLOWED_HOSTS = [] @@ -137,4 +137,4 @@ INTERNAL_IPS = [ "127.0.0.1", -] \ No newline at end of file +] diff --git a/cinema_service/urls.py b/cinema_service/urls.py index e8483a8c..533a67a2 100644 --- a/cinema_service/urls.py +++ b/cinema_service/urls.py @@ -5,4 +5,4 @@ urlpatterns = [ path("admin/", admin.site.urls), path("api/cinema/", include("cinema.urls", namespace="cinema")), -] + debug_toolbar_urls() +] From b63ac8bcad5d0df58f265ba0617d4405dcf876b0 Mon Sep 17 00:00:00 2001 From: Anastasiia Karpenko Date: Wed, 11 Dec 2024 18:11:31 +0200 Subject: [PATCH 4/5] code refactore --- cinema_service/settings.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 92971ae4..e168ef04 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -12,8 +12,6 @@ from pathlib import Path -from decouple import config - # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -22,7 +20,9 @@ # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = config("SECRET_KEY") +SECRET_KEY = ( + "django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" +) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False From c6f5d9c3fcd2db9aa92bfc1a33bdc5e523cf0897 Mon Sep 17 00:00:00 2001 From: Anastasiia Karpenko Date: Wed, 11 Dec 2024 18:13:09 +0200 Subject: [PATCH 5/5] code refactore --- cinema_service/urls.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cinema_service/urls.py b/cinema_service/urls.py index 533a67a2..229767ed 100644 --- a/cinema_service/urls.py +++ b/cinema_service/urls.py @@ -1,4 +1,3 @@ -from debug_toolbar.toolbar import debug_toolbar_urls from django.contrib import admin from django.urls import path, include