Skip to content

Commit

Permalink
solution
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiik05 committed Dec 12, 2024
1 parent efd4b75 commit 7d53d23
Show file tree
Hide file tree
Showing 12 changed files with 215 additions and 97 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),
),
]
29 changes: 13 additions & 16 deletions cinema/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ 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
)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)

def __str__(self):
return str(self.created_at)
Expand All @@ -78,20 +77,19 @@ class Ticket(models.Model):
movie_session = models.ForeignKey(
MovieSession, on_delete=models.CASCADE, related_name="tickets"
)
order = models.ForeignKey(
Order, on_delete=models.CASCADE, related_name="tickets"
)
order = models.ForeignKey(Order, on_delete=models.CASCADE,
related_name="tickets")
row = models.IntegerField()
seat = models.IntegerField()

def clean(self):
for ticket_attr_value, ticket_attr_name, cinema_hall_attr_name in [
for (ticket_attr_value, ticket_attr_name,
cinema_hall_attr_name) in [
(self.row, "row", "rows"),
(self.seat, "seat", "seats_in_row"),
]:
count_attrs = getattr(
self.movie_session.cinema_hall, cinema_hall_attr_name
)
count_attrs = getattr(self.movie_session.cinema_hall,
cinema_hall_attr_name)
if not (1 <= ticket_attr_value <= count_attrs):
raise ValidationError(
{
Expand All @@ -110,14 +108,13 @@ def save(
update_fields=None,
):
self.full_clean()
super(Ticket, self).save(
force_insert, force_update, using, update_fields
)
super(Ticket, self).save(force_insert, force_update, using,
update_fields)

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

class Meta:
unique_together = ("movie_session", "row", "seat")
ordering = ("row",)
79 changes: 70 additions & 9 deletions cinema/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from django.db import transaction
from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator

from cinema.models import Genre, Actor, CinemaHall, Movie, MovieSession
from cinema.models import (Genre,
Actor,
CinemaHall,
Movie,
MovieSession,
Order,
Ticket)


class GenreSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -28,9 +36,9 @@ class Meta:


class MovieListSerializer(MovieSerializer):
genres = serializers.SlugRelatedField(
many=True, read_only=True, slug_field="name"
)
genres = serializers.SlugRelatedField(many=True,
read_only=True,
slug_field="name")
actors = serializers.SlugRelatedField(
many=True, read_only=True, slug_field="full_name"
)
Expand All @@ -52,13 +60,14 @@ class Meta:


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
)
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
)
tickets_available = serializers.IntegerField(read_only=True)

class Meta:
model = MovieSession
Expand All @@ -68,13 +77,65 @@ class Meta:
"movie_title",
"cinema_hall_name",
"cinema_hall_capacity",
"tickets_available",
)


class TicketDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Ticket
fields = (
"row",
"seat",
)


class MovieSessionDetailSerializer(MovieSessionSerializer):
movie = MovieListSerializer(many=False, read_only=True)
cinema_hall = CinemaHallSerializer(many=False, read_only=True)
taken_places = TicketDetailSerializer(many=True, source="tickets",
read_only=True)

class Meta:
model = MovieSession
fields = ("id", "show_time", "movie", "cinema_hall")
fields = ("id", "show_time", "movie", "cinema_hall", "taken_places")


class TicketSerializer(serializers.ModelSerializer):
movie_session = MovieSessionListSerializer(read_only=True)

class Meta:
model = Ticket
fields = (
"id",
"row",
"seat",
"movie_session",
)
validators = [
UniqueTogetherValidator(
queryset=Ticket.objects.all(), fields=("row",
"seat",
"movie_session")
)
]


class OrderSerializer(serializers.ModelSerializer):
tickets = TicketSerializer(many=True, read_only=False, allow_empty=False)

class Meta:
model = Order
fields = (
"id",
"tickets",
"created_at",
)

def create(self, validated_data):
with transaction.atomic():
tickets_data = validated_data.pop("tickets")
order = Order.objects.create(**validated_data)
for ticket_data in tickets_data:
Ticket.objects.create(order=order, **ticket_data)
return order
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
20 changes: 5 additions & 15 deletions cinema/tests/test_movie_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ def setUp(self):
self.comedy = Genre.objects.create(
name="Comedy",
)
self.actress = Actor.objects.create(
first_name="Kate", last_name="Winslet"
)
self.actress = Actor.objects.create(first_name="Kate", last_name="Winslet")
self.movie = Movie.objects.create(
title="Titanic",
description="Titanic description",
Expand All @@ -42,21 +40,15 @@ def test_get_movies(self):
self.assertEqual(movies.data[0][field], titanic[field])

def test_get_movies_with_genres_filtering(self):
movies = self.client.get(
f"/api/cinema/movies/?genres={self.comedy.id}"
)
movies = self.client.get(f"/api/cinema/movies/?genres={self.comedy.id}")
self.assertEqual(len(movies.data), 1)
movies = self.client.get(
f"/api/cinema/movies/?genres={self.comedy.id},2,3"
)
movies = self.client.get(f"/api/cinema/movies/?genres={self.comedy.id},2,3")
self.assertEqual(len(movies.data), 1)
movies = self.client.get("/api/cinema/movies/?genres=123213")
self.assertEqual(len(movies.data), 0)

def test_get_movies_with_actors_filtering(self):
movies = self.client.get(
f"/api/cinema/movies/?actors={self.actress.id}"
)
movies = self.client.get(f"/api/cinema/movies/?actors={self.actress.id}")
self.assertEqual(len(movies.data), 1)
movies = self.client.get(f"/api/cinema/movies/?actors={123}")
self.assertEqual(len(movies.data), 0)
Expand Down Expand Up @@ -111,9 +103,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
27 changes: 6 additions & 21 deletions cinema/tests/test_movie_session_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,7 @@ def setUp(self):
self.movie_session = MovieSession.objects.create(
movie=self.movie,
cinema_hall=self.cinema_hall,
show_time=datetime.datetime(
year=2022,
month=9,
day=2,
hour=9
),
show_time=datetime.datetime(year=2022, month=9, day=2, hour=9),
)

def test_get_movie_sessions(self):
Expand All @@ -51,20 +46,14 @@ 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_get_movie_sessions_filtered_by_date(self):
movie_sessions = self.client.get(
"/api/cinema/movie_sessions/?date=2022-09-02"
)
movie_sessions = self.client.get("/api/cinema/movie_sessions/?date=2022-09-02")
self.assertEqual(movie_sessions.status_code, status.HTTP_200_OK)
self.assertEqual(len(movie_sessions.data), 1)

movie_sessions = self.client.get(
"/api/cinema/movie_sessions/?date=2022-09-01"
)
movie_sessions = self.client.get("/api/cinema/movie_sessions/?date=2022-09-01")
self.assertEqual(movie_sessions.status_code, status.HTTP_200_OK)
self.assertEqual(len(movie_sessions.data), 0)

Expand All @@ -75,9 +64,7 @@ def test_get_movie_sessions_filtered_by_movie(self):
self.assertEqual(movie_sessions.status_code, status.HTTP_200_OK)
self.assertEqual(len(movie_sessions.data), 1)

movie_sessions = self.client.get(
"/api/cinema/movie_sessions/?movie=1234"
)
movie_sessions = self.client.get("/api/cinema/movie_sessions/?movie=1234")
self.assertEqual(movie_sessions.status_code, status.HTTP_200_OK)
self.assertEqual(len(movie_sessions.data), 0)

Expand Down Expand Up @@ -117,9 +104,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
12 changes: 3 additions & 9 deletions cinema/tests/test_order_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ def setUp(self):
self.comedy = Genre.objects.create(
name="Comedy",
)
self.actress = Actor.objects.create(
first_name="Kate", last_name="Winslet"
)
self.actress = Actor.objects.create(first_name="Kate", last_name="Winslet")
self.movie = Movie.objects.create(
title="Titanic",
description="Titanic description",
Expand Down Expand Up @@ -73,12 +71,8 @@ def test_movie_session_detail_tickets(self):
f"/api/cinema/movie_sessions/{self.movie_session.id}/"
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
response.data["taken_places"][0]["row"], self.ticket.row
)
self.assertEqual(
response.data["taken_places"][0]["seat"], self.ticket.seat
)
self.assertEqual(response.data["taken_places"][0]["row"], self.ticket.row)
self.assertEqual(response.data["taken_places"][0]["seat"], self.ticket.seat)

def test_movie_session_list_tickets_available(self):
response = self.client.get(f"/api/cinema/movie_sessions/")
Expand Down
Loading

0 comments on commit 7d53d23

Please sign in to comment.