Skip to content

Commit

Permalink
Solution
Browse files Browse the repository at this point in the history
  • Loading branch information
TylerJack239 committed Dec 2, 2024
1 parent 1f225be commit c86b00f
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 44 deletions.
6 changes: 3 additions & 3 deletions cinema/migrations/0003_movie_duration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
class Migration(migrations.Migration):

dependencies = [
('cinema', '0002_initial'),
("cinema", "0002_initial"),
]

operations = [
migrations.AddField(
model_name='movie',
name='duration',
model_name="movie",
name="duration",
field=models.IntegerField(default=123),
preserve_default=False,
),
Expand Down
6 changes: 3 additions & 3 deletions cinema/migrations/0004_alter_genre_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
class Migration(migrations.Migration):

dependencies = [
('cinema', '0003_movie_duration'),
("cinema", "0003_movie_duration"),
]

operations = [
migrations.AlterField(
model_name='genre',
name='name',
model_name="genre",
name="name",
field=models.CharField(max_length=255, unique=True),
),
]
23 changes: 23 additions & 0 deletions cinema/migrations/0005_alter_movie_actors_alter_movie_genres.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.0.4 on 2024-12-02 13:13

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("cinema", "0004_alter_genre_name"),
]

operations = [
migrations.AlterField(
model_name="movie",
name="actors",
field=models.ManyToManyField(related_name="movies", to="cinema.actor"),
),
migrations.AlterField(
model_name="movie",
name="genres",
field=models.ManyToManyField(related_name="movies", to="cinema.genre"),
),
]
43 changes: 43 additions & 0 deletions cinema/migrations/0006_alter_moviesession_cinema_hall_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 4.0.4 on 2024-12-02 13:14

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("cinema", "0005_alter_movie_actors_alter_movie_genres"),
]

operations = [
migrations.AlterField(
model_name="moviesession",
name="cinema_hall",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="sessions",
to="cinema.cinemahall",
),
),
migrations.AlterField(
model_name="moviesession",
name="movie",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="sessions",
to="cinema.movie",
),
),
migrations.AlterField(
model_name="order",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="orders",
to=settings.AUTH_USER_MODEL,
),
),
]
45 changes: 32 additions & 13 deletions cinema/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -35,8 +39,8 @@ class Movie(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
duration = models.IntegerField()
genres = models.ManyToManyField(Genre)
actors = models.ManyToManyField(Actor)
genres = models.ManyToManyField(Genre, related_name="movies")
actors = models.ManyToManyField(Actor, related_name="movies")

class Meta:
ordering = ["title"]
Expand All @@ -47,8 +51,14 @@ def __str__(self):

class MovieSession(models.Model):
show_time = models.DateTimeField()
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
cinema_hall = models.ForeignKey(CinemaHall, on_delete=models.CASCADE)
movie = models.ForeignKey(
Movie,
on_delete=models.CASCADE,
related_name="sessions")

cinema_hall = models.ForeignKey(
CinemaHall, on_delete=models.CASCADE, related_name="sessions"
)

class Meta:
ordering = ["-show_time"]
Expand All @@ -59,8 +69,11 @@ def __str__(self):

class Order(models.Model):
created_at = models.DateTimeField(auto_now_add=True)

user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="orders"
)

def __str__(self):
Expand All @@ -72,11 +85,16 @@ class Meta:

class Ticket(models.Model):
movie_session = models.ForeignKey(
MovieSession, on_delete=models.CASCADE, related_name="tickets"
MovieSession,
on_delete=models.CASCADE,
related_name="tickets"
)

order = models.ForeignKey(
Order, on_delete=models.CASCADE, related_name="tickets"
)
Order,
on_delete=models.CASCADE,
related_name="tickets")

row = models.IntegerField()
seat = models.IntegerField()

Expand All @@ -86,8 +104,9 @@ def clean(self):
(self.seat, "seat", "count_seats_in_row"),
]:
count_attrs = getattr(
self.movie_session.cinema_hall, cinema_hall_attr_name
)
self.movie_session.cinema_hall,
cinema_hall_attr_name)

if not (1 <= ticket_attr_value <= count_attrs):
raise ValidationError(
{
Expand All @@ -99,9 +118,9 @@ def clean(self):
)

def __str__(self):
return (
f"{str(self.movie_session)} (row: {self.row}, seat: {self.seat})"
)
return (f""
f"{str(self.movie_session)}"
f" (row: {self.row}, seat: {self.seat})")

class Meta:
unique_together = ("movie_session", "row", "seat")
89 changes: 88 additions & 1 deletion cinema/serializers.py
Original file line number Diff line number Diff line change
@@ -1 +1,88 @@
# write serializers here
from rest_framework import serializers
from cinema.models import (Actor,
CinemaHall,
Movie,
MovieSession,
Order,
Ticket,
Genre)


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 = (
"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", "duration", "description", "genres", "actors")


class MovieListSerializer(MovieSerializer):
genres = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field="name")

actors = serializers.StringRelatedField(many=True)

class Meta:
model = Movie
fields = "__all__"


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 = ("id", "show_time", "movie", "cinema_hall")
read_only_fields = ("id",)


class MovieSessionListSerializer(MovieSessionSerializer):
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",
)
read_only_fields = ("id",)


class MovieSessionRetrieveSerializer(MovieSessionSerializer):
movie = MovieListSerializer(many=False, read_only=True)
cinema_hall = CinemaHallSerializer(many=False, read_only=True)
4 changes: 1 addition & 3 deletions cinema/tests/test_actor_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ def test_get_actors(self):
response = self.client.get("/api/cinema/actors/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
actors_full_names = [actor["full_name"] for actor in response.data]
self.assertEqual(
sorted(actors_full_names), ["George Clooney", "Keanu Reeves"]
)
self.assertEqual(sorted(actors_full_names), ["George Clooney", "Keanu Reeves"])

def test_post_actors(self):
response = self.client.post(
Expand Down
12 changes: 3 additions & 9 deletions cinema/tests/test_cinema_hall_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ def test_get_cinema_halls(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data[0]["name"], blue_hall["name"])
self.assertEqual(response.data[0]["rows"], blue_hall["rows"])
self.assertEqual(
response.data[0]["seats_in_row"], blue_hall["seats_in_row"]
)
self.assertEqual(response.data[0]["seats_in_row"], blue_hall["seats_in_row"])
vip_hall = {
"name": "VIP",
"rows": 6,
Expand All @@ -43,9 +41,7 @@ def test_get_cinema_halls(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data[1]["name"], vip_hall["name"])
self.assertEqual(response.data[1]["rows"], vip_hall["rows"])
self.assertEqual(
response.data[1]["seats_in_row"], vip_hall["seats_in_row"]
)
self.assertEqual(response.data[1]["seats_in_row"], vip_hall["seats_in_row"])

def test_post_cinema_halls(self):
response = self.client.post(
Expand All @@ -72,9 +68,7 @@ def test_get_cinema_hall(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["name"], vip_hall["name"])
self.assertEqual(response.data["rows"], vip_hall["rows"])
self.assertEqual(
response.data["seats_in_row"], vip_hall["seats_in_row"]
)
self.assertEqual(response.data["seats_in_row"], vip_hall["seats_in_row"])
self.assertEqual(response.data["capacity"], vip_hall["capacity"])

def test_get_invalid_cinema_hall(self):
Expand Down
4 changes: 1 addition & 3 deletions cinema/tests/test_movie_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ def test_get_movie(self):
self.assertEqual(response.data["genres"][1]["name"], "Comedy")
self.assertEqual(response.data["actors"][0]["first_name"], "Kate")
self.assertEqual(response.data["actors"][0]["last_name"], "Winslet")
self.assertEqual(
response.data["actors"][0]["full_name"], "Kate Winslet"
)
self.assertEqual(response.data["actors"][0]["full_name"], "Kate Winslet")

def test_get_invalid_movie(self):
response = self.client.get("/api/cinema/movies/100/")
Expand Down
8 changes: 2 additions & 6 deletions cinema/tests/test_movie_session_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ def test_get_movie_sessions(self):
}
self.assertEqual(movie_sessions.status_code, status.HTTP_200_OK)
for field in movie_session:
self.assertEqual(
movie_sessions.data[0][field], movie_session[field]
)
self.assertEqual(movie_sessions.data[0][field], movie_session[field])

def test_post_movie_session(self):
movies = self.client.post(
Expand All @@ -67,9 +65,7 @@ def test_get_movie_session(self):
response = self.client.get("/api/cinema/movie_sessions/1/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["movie"]["title"], "Titanic")
self.assertEqual(
response.data["movie"]["description"], "Titanic description"
)
self.assertEqual(response.data["movie"]["description"], "Titanic description")
self.assertEqual(response.data["movie"]["duration"], 123)
self.assertEqual(response.data["movie"]["genres"], ["Drama", "Comedy"])
self.assertEqual(response.data["movie"]["actors"], ["Kate Winslet"])
Expand Down
24 changes: 23 additions & 1 deletion cinema/urls.py
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
# write urls here
from django.urls import path, include
from rest_framework import routers
from cinema.views import (
CinemaHallViewSet,
GenreViewSet,
ActorViewSet,
MovieViewSet,
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)),
]
Loading

0 comments on commit c86b00f

Please sign in to comment.