From c9efc564d8f037d424fcbe73b5020362644272fc Mon Sep 17 00:00:00 2001 From: Olexandr Date: Sun, 29 Oct 2023 09:27:02 +0200 Subject: [PATCH 1/4] eeettt5 --- .run/pytest in test_main.py.run.xml | 20 ++++++ db/migrations/0001_initial.py | 42 +++++++++++-- db/migrations/0002_use654567.py | 21 +++++++ db/migrations/0003_delete_use654567.py | 16 +++++ db/migrations/0004_alter_order_created_at.py | 18 ++++++ db/migrations/0005_alter_order_created_at.py | 18 ++++++ ...ket_unique_order_row_seat_order_session.py | 17 ++++++ ...order_options_moviesession_row_and_more.py | 27 ++++++++ db/models.py | 61 ++++++++++++++++++- services/movie.py | 8 ++- services/movie_session.py | 10 ++- services/order.py | 37 +++++++++++ services/user.py | 42 +++++++++++++ settings.py | 4 ++ 14 files changed, 331 insertions(+), 10 deletions(-) create mode 100644 .run/pytest in test_main.py.run.xml create mode 100644 db/migrations/0002_use654567.py create mode 100644 db/migrations/0003_delete_use654567.py create mode 100644 db/migrations/0004_alter_order_created_at.py create mode 100644 db/migrations/0005_alter_order_created_at.py create mode 100644 db/migrations/0006_ticket_unique_order_row_seat_order_session.py create mode 100644 db/migrations/0007_alter_order_options_moviesession_row_and_more.py create mode 100644 services/order.py create mode 100644 services/user.py diff --git a/.run/pytest in test_main.py.run.xml b/.run/pytest in test_main.py.run.xml new file mode 100644 index 000000000..24f854b0c --- /dev/null +++ b/.run/pytest in test_main.py.run.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/db/migrations/0001_initial.py b/db/migrations/0001_initial.py index 8578293c0..4851eaba6 100644 --- a/db/migrations/0001_initial.py +++ b/db/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 4.0.2 on 2022-06-15 12:37 +# Generated by Django 4.0.2 on 2023-10-28 23:51 +from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -9,6 +10,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -40,10 +42,10 @@ class Migration(migrations.Migration): name='Movie', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255)), + ('title', models.CharField(db_index=True, max_length=255)), ('description', models.TextField()), - ('actors', models.ManyToManyField(to='db.Actor')), - ('genres', models.ManyToManyField(to='db.Genre')), + ('actors', models.ManyToManyField(related_name='movies', to='db.Actor')), + ('genres', models.ManyToManyField(related_name='movies', to='db.Genre')), ], ), migrations.CreateModel( @@ -51,8 +53,36 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('show_time', models.DateTimeField()), - ('cinema_hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.cinemahall')), - ('movie', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.movie')), + ('cinema_hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_sessions', to='db.cinemahall')), + ('movie', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_sessions', to='db.movie')), + ], + ), + migrations.CreateModel( + name='Order', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='User', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('row', models.IntegerField()), + ('seat', models.IntegerField()), + ('movie_session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.moviesession')), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_orders', to='db.order')), + ], + ), + migrations.CreateModel( + name='Ticket', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('row', models.IntegerField()), + ('seat', models.IntegerField()), + ('movie_session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.moviesession')), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.order')), ], ), ] diff --git a/db/migrations/0002_use654567.py b/db/migrations/0002_use654567.py new file mode 100644 index 000000000..722ddeade --- /dev/null +++ b/db/migrations/0002_use654567.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.2 on 2023-10-29 08:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Use654567', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('row', models.IntegerField()), + ('seat', models.IntegerField()), + ], + ), + ] diff --git a/db/migrations/0003_delete_use654567.py b/db/migrations/0003_delete_use654567.py new file mode 100644 index 000000000..f898dfe6a --- /dev/null +++ b/db/migrations/0003_delete_use654567.py @@ -0,0 +1,16 @@ +# Generated by Django 4.0.2 on 2023-10-29 08:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0002_use654567'), + ] + + operations = [ + migrations.DeleteModel( + name='Use654567', + ), + ] diff --git a/db/migrations/0004_alter_order_created_at.py b/db/migrations/0004_alter_order_created_at.py new file mode 100644 index 000000000..f9d0f01b5 --- /dev/null +++ b/db/migrations/0004_alter_order_created_at.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2023-10-29 16:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0003_delete_use654567'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='created_at', + field=models.DateTimeField(), + ), + ] diff --git a/db/migrations/0005_alter_order_created_at.py b/db/migrations/0005_alter_order_created_at.py new file mode 100644 index 000000000..36ec2a7b9 --- /dev/null +++ b/db/migrations/0005_alter_order_created_at.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.2 on 2023-10-29 16:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0004_alter_order_created_at'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='created_at', + field=models.DateTimeField(auto_now_add=True), + ), + ] diff --git a/db/migrations/0006_ticket_unique_order_row_seat_order_session.py b/db/migrations/0006_ticket_unique_order_row_seat_order_session.py new file mode 100644 index 000000000..06b2ea3af --- /dev/null +++ b/db/migrations/0006_ticket_unique_order_row_seat_order_session.py @@ -0,0 +1,17 @@ +# Generated by Django 4.0.2 on 2023-10-29 18:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0005_alter_order_created_at'), + ] + + operations = [ + migrations.AddConstraint( + model_name='ticket', + constraint=models.UniqueConstraint(fields=('row', 'seat', 'movie_session'), name='unique_order_row_seat_order_session'), + ), + ] diff --git a/db/migrations/0007_alter_order_options_moviesession_row_and_more.py b/db/migrations/0007_alter_order_options_moviesession_row_and_more.py new file mode 100644 index 000000000..b0f23462c --- /dev/null +++ b/db/migrations/0007_alter_order_options_moviesession_row_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.2 on 2023-11-07 15:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('db', '0006_ticket_unique_order_row_seat_order_session'), + ] + + operations = [ + migrations.AlterModelOptions( + name='order', + options={'ordering': ['-created_at']}, + ), + migrations.AddField( + model_name='moviesession', + name='row', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='moviesession', + name='seat', + field=models.IntegerField(null=True), + ), + ] diff --git a/db/models.py b/db/models.py index 2a3359a63..8d14991b5 100644 --- a/db/models.py +++ b/db/models.py @@ -1,4 +1,7 @@ from django.db import models +from django.contrib.contenttypes.models import ContentType +from django.contrib.auth.models import User +from django.core.exceptions import ValidationError class Genre(models.Model): @@ -17,7 +20,7 @@ def __str__(self) -> str: class Movie(models.Model): - title = models.CharField(max_length=255) + title = models.CharField(max_length=255, db_index=True) description = models.TextField() actors = models.ManyToManyField(to=Actor, related_name="movies") genres = models.ManyToManyField(to=Genre, related_name="movies") @@ -40,6 +43,8 @@ def __str__(self) -> str: class MovieSession(models.Model): + row = models.IntegerField(null=True) + seat = models.IntegerField(null=True) show_time = models.DateTimeField() cinema_hall = models.ForeignKey( to=CinemaHall, on_delete=models.CASCADE, related_name="movie_sessions" @@ -49,4 +54,56 @@ class MovieSession(models.Model): ) def __str__(self) -> str: - return f"{self.movie.title} {str(self.show_time)}" + return f"{self.movie.title} {str(self.show_time)} {self.cinema_hall.rows} {self.cinema_hall.seats_in_row}" + + +class Order(models.Model): + created_at = models.DateTimeField(auto_now_add=True) + user = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='orders') + + class Meta: + ordering = ["-created_at"] + + def __str__(self) -> str: + return str(self.created_at) + +class Ticket(models.Model): + movie_session = models.ForeignKey(to=MovieSession, on_delete=models.CASCADE) + order = models.ForeignKey(Order, on_delete=models.CASCADE) + row = models.IntegerField() + seat = models.IntegerField() + + def clean(self): + max_row = self.movie_session.cinema_hall.rows # Отримати максимальне значення row + max_seat = self.movie_session.cinema_hall.seats_in_row # Отримати максимальне значення seat + + if self.row > max_row: + raise ValidationError({'row': f'row number must be in available range: (1, rows): (1, {max_row})'}) + + if self.seat > max_seat: + raise ValidationError({'seat': f'seat number must be in available range: (1, seats_in_row): (1, {max_seat})'}) + + def save(self, *args, **kwargs): + self.full_clean() + super().save(*args, **kwargs) + + class Meta: + constraints = [ + models.UniqueConstraint( + fields=["row", "seat", "movie_session"], + name="unique_order_row_seat_order_session" + ) + ] + + def __str__(self) -> str: + return f"Matrix 2019-08-19 20:30:00 (row: {self.row}, seat: {self.seat})" + + +class User(models.Model): + movie_session = models.ForeignKey(to=MovieSession, on_delete=models.CASCADE) + order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='user_orders') + row = models.IntegerField() + seat = models.IntegerField() + + def __str__(self) -> str: + return f"Ticket: {self.order}, (row: {self.row}, seat: {self.seat})" diff --git a/services/movie.py b/services/movie.py index 4d0f63237..6198bcc67 100644 --- a/services/movie.py +++ b/services/movie.py @@ -1,11 +1,12 @@ from django.db.models import QuerySet - +from django.db import transaction from db.models import Movie def get_movies( genres_ids: list[int] = None, actors_ids: list[int] = None, + title=None, ) -> QuerySet: queryset = Movie.objects.all() @@ -15,6 +16,10 @@ def get_movies( if actors_ids: queryset = queryset.filter(actors__id__in=actors_ids) + if title: + # фільтрувати фільми за назвою, якщо аргумент `title` переданий + return Movie.objects.filter(title__icontains=title) + return queryset @@ -22,6 +27,7 @@ def get_movie_by_id(movie_id: int) -> Movie: return Movie.objects.get(id=movie_id) +@transaction.atomic def create_movie( movie_title: str, movie_description: str, diff --git a/services/movie_session.py b/services/movie_session.py index f326a082e..73eb4ac23 100644 --- a/services/movie_session.py +++ b/services/movie_session.py @@ -1,6 +1,6 @@ from django.db.models import QuerySet -from db.models import MovieSession +from db.models import MovieSession, Ticket def create_movie_session( @@ -42,3 +42,11 @@ def update_movie_session( def delete_movie_session_by_id(session_id: int) -> None: MovieSession.objects.get(id=session_id).delete() + + +def get_taken_seats(movie_session_id): + taken_seats = [] + tickets = Ticket.objects.filter(movie_session_id=movie_session_id) + for ticket in tickets: + taken_seats.append({"row": ticket.row, "seat": ticket.seat}) + return taken_seats \ No newline at end of file diff --git a/services/order.py b/services/order.py new file mode 100644 index 000000000..4c3f8b965 --- /dev/null +++ b/services/order.py @@ -0,0 +1,37 @@ +import distutils +from datetime import date +from db.models import Order +from django.db import transaction +from typing import List +from db.models import MovieSession, User, Ticket +from django.contrib.auth.models import User + + +@transaction.atomic +def create_order(tickets: List[dict], username, date=None): + user, created = User.objects.get_or_create(username=username) + order, created = Order.objects.get_or_create(user=user) + if date is not None: + order.created_at = date + order.save() + for ticket_data in tickets: + row = ticket_data.get("row") + seat = ticket_data.get("seat") + movie_session = MovieSession.objects.get(pk=1) + ticket, created = Ticket.objects.get_or_create(row=row, seat=seat, movie_session=movie_session, order=order) + ticket.order = order + ticket.save() + # if date is not None: + # Order.objects.update_or_create(user=username, created_at=date) + # Ticket.objects.update_or_create(row=row, seat=seat, movie_session=movie_session) + # else: + # Order.objects.update_or_create(user=username) + # Ticket.objects.update_or_create(row=row, seat=seat, movie_session=movie_session) + #return + + +def get_orders(username=None): + if username is not None: + return Order.objects.filter(user__username=username).order_by("created_at") + elif username is None: + return Order.objects.all().order_by("-created_at") diff --git a/services/user.py b/services/user.py new file mode 100644 index 000000000..be587f855 --- /dev/null +++ b/services/user.py @@ -0,0 +1,42 @@ +from django.contrib.auth.hashers import make_password +from django.contrib.auth.models import User + + +def create_user( username, password, user_id=None, email=None, first_name=None, last_name=None): + try: + user, created = User.objects.update_or_create(id=user_id, defaults={'username': username, 'password': make_password(password)}) + if email is not None: + user.email = email + if first_name is not None: + user.first_name = first_name + if last_name is not None: + user.last_name = last_name + user.save() + return user + except User.DoesNotExist: + return None + + +def get_user(user_id): + return User.objects.get(id=user_id) + +def update_user(user_id, username=None, password=None, email=None, first_name=None, last_name=None): + try: + user = User.objects.get(id=user_id) + except User.DoesNotExist: + return None + + if username is not None: + user.username = username + if password is not None: + user.set_password(password) + if email is not None: + user.email = email + if first_name is not None: + user.first_name = first_name + if last_name is not None: + user.last_name = last_name + + user.save() + return user + diff --git a/settings.py b/settings.py index f25910b30..d02fb68ef 100644 --- a/settings.py +++ b/settings.py @@ -25,4 +25,8 @@ INSTALLED_APPS = [ "db", + "django.contrib.auth", + "django.contrib.contenttypes", ] + +AUTH_USER_MODEL = "auth.User" From 34beb0c3877c8de632d01586389808ac2c03a8b8 Mon Sep 17 00:00:00 2001 From: melnikalex1977 <53905763+melnikalex1977@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:58:59 +0200 Subject: [PATCH 2/4] Delete .run directory --- .run/pytest in test_main.py.run.xml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 .run/pytest in test_main.py.run.xml diff --git a/.run/pytest in test_main.py.run.xml b/.run/pytest in test_main.py.run.xml deleted file mode 100644 index 24f854b0c..000000000 --- a/.run/pytest in test_main.py.run.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file From 0277f614ad8d37d44266310cfdb8cf9607167fcb Mon Sep 17 00:00:00 2001 From: melnikalex1977 <53905763+melnikalex1977@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:58:59 +0200 Subject: [PATCH 3/4] Delete .run directory --- .run/pytest in test_main.py.run.xml | 20 ------ db/migrations/0002_use654567.py | 21 ------ db/migrations/0003_delete_use654567.py | 16 ----- db/migrations/0004_alter_order_created_at.py | 18 ------ db/migrations/0005_alter_order_created_at.py | 18 ------ ...ket_unique_order_row_seat_order_session.py | 17 ----- ...order_options_moviesession_row_and_more.py | 27 -------- db/models.py | 64 +++++++++++-------- settings.py | 4 +- 9 files changed, 41 insertions(+), 164 deletions(-) delete mode 100644 .run/pytest in test_main.py.run.xml delete mode 100644 db/migrations/0002_use654567.py delete mode 100644 db/migrations/0003_delete_use654567.py delete mode 100644 db/migrations/0004_alter_order_created_at.py delete mode 100644 db/migrations/0005_alter_order_created_at.py delete mode 100644 db/migrations/0006_ticket_unique_order_row_seat_order_session.py delete mode 100644 db/migrations/0007_alter_order_options_moviesession_row_and_more.py diff --git a/.run/pytest in test_main.py.run.xml b/.run/pytest in test_main.py.run.xml deleted file mode 100644 index 24f854b0c..000000000 --- a/.run/pytest in test_main.py.run.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/db/migrations/0002_use654567.py b/db/migrations/0002_use654567.py deleted file mode 100644 index 722ddeade..000000000 --- a/db/migrations/0002_use654567.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 08:19 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Use654567', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('row', models.IntegerField()), - ('seat', models.IntegerField()), - ], - ), - ] diff --git a/db/migrations/0003_delete_use654567.py b/db/migrations/0003_delete_use654567.py deleted file mode 100644 index f898dfe6a..000000000 --- a/db/migrations/0003_delete_use654567.py +++ /dev/null @@ -1,16 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 08:20 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0002_use654567'), - ] - - operations = [ - migrations.DeleteModel( - name='Use654567', - ), - ] diff --git a/db/migrations/0004_alter_order_created_at.py b/db/migrations/0004_alter_order_created_at.py deleted file mode 100644 index f9d0f01b5..000000000 --- a/db/migrations/0004_alter_order_created_at.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 16:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0003_delete_use654567'), - ] - - operations = [ - migrations.AlterField( - model_name='order', - name='created_at', - field=models.DateTimeField(), - ), - ] diff --git a/db/migrations/0005_alter_order_created_at.py b/db/migrations/0005_alter_order_created_at.py deleted file mode 100644 index 36ec2a7b9..000000000 --- a/db/migrations/0005_alter_order_created_at.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 16:38 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0004_alter_order_created_at'), - ] - - operations = [ - migrations.AlterField( - model_name='order', - name='created_at', - field=models.DateTimeField(auto_now_add=True), - ), - ] diff --git a/db/migrations/0006_ticket_unique_order_row_seat_order_session.py b/db/migrations/0006_ticket_unique_order_row_seat_order_session.py deleted file mode 100644 index 06b2ea3af..000000000 --- a/db/migrations/0006_ticket_unique_order_row_seat_order_session.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 18:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0005_alter_order_created_at'), - ] - - operations = [ - migrations.AddConstraint( - model_name='ticket', - constraint=models.UniqueConstraint(fields=('row', 'seat', 'movie_session'), name='unique_order_row_seat_order_session'), - ), - ] diff --git a/db/migrations/0007_alter_order_options_moviesession_row_and_more.py b/db/migrations/0007_alter_order_options_moviesession_row_and_more.py deleted file mode 100644 index b0f23462c..000000000 --- a/db/migrations/0007_alter_order_options_moviesession_row_and_more.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.0.2 on 2023-11-07 15:14 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0006_ticket_unique_order_row_seat_order_session'), - ] - - operations = [ - migrations.AlterModelOptions( - name='order', - options={'ordering': ['-created_at']}, - ), - migrations.AddField( - model_name='moviesession', - name='row', - field=models.IntegerField(null=True), - ), - migrations.AddField( - model_name='moviesession', - name='seat', - field=models.IntegerField(null=True), - ), - ] diff --git a/db/models.py b/db/models.py index 8d14991b5..5f44eabf4 100644 --- a/db/models.py +++ b/db/models.py @@ -1,7 +1,7 @@ -from django.db import models -from django.contrib.contenttypes.models import ContentType -from django.contrib.auth.models import User +from django.conf import settings +from django.contrib.auth.models import AbstractUser from django.core.exceptions import ValidationError +from django.db import models class Genre(models.Model): @@ -43,8 +43,6 @@ def __str__(self) -> str: class MovieSession(models.Model): - row = models.IntegerField(null=True) - seat = models.IntegerField(null=True) show_time = models.DateTimeField() cinema_hall = models.ForeignKey( to=CinemaHall, on_delete=models.CASCADE, related_name="movie_sessions" @@ -54,12 +52,16 @@ class MovieSession(models.Model): ) def __str__(self) -> str: - return f"{self.movie.title} {str(self.show_time)} {self.cinema_hall.rows} {self.cinema_hall.seats_in_row}" + return f"{self.movie.title} {self.show_time} {self.cinema_hall.rows} {self.cinema_hall.seats_in_row}" class Order(models.Model): created_at = models.DateTimeField(auto_now_add=True) - user = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='orders') + user = models.ForeignKey( + to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="orders" + ) class Meta: ordering = ["-created_at"] @@ -67,23 +69,35 @@ class Meta: def __str__(self) -> str: return str(self.created_at) + class Ticket(models.Model): - movie_session = models.ForeignKey(to=MovieSession, on_delete=models.CASCADE) + movie_session = models.ForeignKey( + to=MovieSession, + on_delete=models.CASCADE + ) order = models.ForeignKey(Order, on_delete=models.CASCADE) row = models.IntegerField() seat = models.IntegerField() - def clean(self): - max_row = self.movie_session.cinema_hall.rows # Отримати максимальне значення row - max_seat = self.movie_session.cinema_hall.seats_in_row # Отримати максимальне значення seat + def clean(self) -> None: + max_row = self.movie_session.cinema_hall.rows + max_seat = self.movie_session.cinema_hall.seats_in_row if self.row > max_row: - raise ValidationError({'row': f'row number must be in available range: (1, rows): (1, {max_row})'}) + raise ValidationError( + {"row": + f"row number must be in available range: " + f"(1, rows): (1, {max_row})"} + ) if self.seat > max_seat: - raise ValidationError({'seat': f'seat number must be in available range: (1, seats_in_row): (1, {max_seat})'}) + raise ValidationError( + {"seat": f"seat number must " + f"be in available range: (1, seats_in_row): " + f"(1, {max_seat})"} + ) - def save(self, *args, **kwargs): + def save(self, *args, **kwargs) -> None: self.full_clean() super().save(*args, **kwargs) @@ -92,18 +106,18 @@ class Meta: models.UniqueConstraint( fields=["row", "seat", "movie_session"], name="unique_order_row_seat_order_session" - ) + ) ] - def __str__(self) -> str: - return f"Matrix 2019-08-19 20:30:00 (row: {self.row}, seat: {self.seat})" - + def __str__(self) -> str : + return ( + f"Matrix 2019-08-19 20:30:00 " # noqa + f"(row: {self.row}, " + f"seat: {self.seat})" + ) -class User(models.Model): - movie_session = models.ForeignKey(to=MovieSession, on_delete=models.CASCADE) - order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='user_orders') - row = models.IntegerField() - seat = models.IntegerField() - def __str__(self) -> str: - return f"Ticket: {self.order}, (row: {self.row}, seat: {self.seat})" +class User(AbstractUser): + USERNAME_FIELD = "username" + REQUIRED_FIELDS = [] + pass diff --git a/settings.py b/settings.py index d02fb68ef..4656ed778 100644 --- a/settings.py +++ b/settings.py @@ -24,9 +24,9 @@ USE_TZ = False INSTALLED_APPS = [ - "db", "django.contrib.auth", "django.contrib.contenttypes", + "db", ] -AUTH_USER_MODEL = "auth.User" +AUTH_USER_MODEL = "db.User" From 3291d180c46d9b6813d286cbd8205511095186a6 Mon Sep 17 00:00:00 2001 From: melnikalex1977 <53905763+melnikalex1977@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:58:59 +0200 Subject: [PATCH 4/4] Delete .run directory --- .run/pytest in test_main.py.run.xml | 20 ------ db/migrations/0001_initial.py | 42 ++---------- db/migrations/0002_use654567.py | 21 ------ db/migrations/0003_delete_use654567.py | 16 ----- db/migrations/0004_alter_order_created_at.py | 18 ------ db/migrations/0005_alter_order_created_at.py | 18 ------ ...ket_unique_order_row_seat_order_session.py | 17 ----- ...order_options_moviesession_row_and_more.py | 27 -------- db/models.py | 64 +++++++++++-------- services/movie.py | 5 +- services/movie_session.py | 4 +- services/order.py | 34 +++++----- services/user.py | 32 ++++++++-- settings.py | 4 +- 14 files changed, 96 insertions(+), 226 deletions(-) delete mode 100644 .run/pytest in test_main.py.run.xml delete mode 100644 db/migrations/0002_use654567.py delete mode 100644 db/migrations/0003_delete_use654567.py delete mode 100644 db/migrations/0004_alter_order_created_at.py delete mode 100644 db/migrations/0005_alter_order_created_at.py delete mode 100644 db/migrations/0006_ticket_unique_order_row_seat_order_session.py delete mode 100644 db/migrations/0007_alter_order_options_moviesession_row_and_more.py diff --git a/.run/pytest in test_main.py.run.xml b/.run/pytest in test_main.py.run.xml deleted file mode 100644 index 24f854b0c..000000000 --- a/.run/pytest in test_main.py.run.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/db/migrations/0001_initial.py b/db/migrations/0001_initial.py index 4851eaba6..8578293c0 100644 --- a/db/migrations/0001_initial.py +++ b/db/migrations/0001_initial.py @@ -1,6 +1,5 @@ -# Generated by Django 4.0.2 on 2023-10-28 23:51 +# Generated by Django 4.0.2 on 2022-06-15 12:37 -from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -10,7 +9,6 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -42,10 +40,10 @@ class Migration(migrations.Migration): name='Movie', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(db_index=True, max_length=255)), + ('title', models.CharField(max_length=255)), ('description', models.TextField()), - ('actors', models.ManyToManyField(related_name='movies', to='db.Actor')), - ('genres', models.ManyToManyField(related_name='movies', to='db.Genre')), + ('actors', models.ManyToManyField(to='db.Actor')), + ('genres', models.ManyToManyField(to='db.Genre')), ], ), migrations.CreateModel( @@ -53,36 +51,8 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('show_time', models.DateTimeField()), - ('cinema_hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_sessions', to='db.cinemahall')), - ('movie', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_sessions', to='db.movie')), - ], - ), - migrations.CreateModel( - name='Order', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='User', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('row', models.IntegerField()), - ('seat', models.IntegerField()), - ('movie_session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.moviesession')), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_orders', to='db.order')), - ], - ), - migrations.CreateModel( - name='Ticket', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('row', models.IntegerField()), - ('seat', models.IntegerField()), - ('movie_session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.moviesession')), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.order')), + ('cinema_hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.cinemahall')), + ('movie', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.movie')), ], ), ] diff --git a/db/migrations/0002_use654567.py b/db/migrations/0002_use654567.py deleted file mode 100644 index 722ddeade..000000000 --- a/db/migrations/0002_use654567.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 08:19 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Use654567', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('row', models.IntegerField()), - ('seat', models.IntegerField()), - ], - ), - ] diff --git a/db/migrations/0003_delete_use654567.py b/db/migrations/0003_delete_use654567.py deleted file mode 100644 index f898dfe6a..000000000 --- a/db/migrations/0003_delete_use654567.py +++ /dev/null @@ -1,16 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 08:20 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0002_use654567'), - ] - - operations = [ - migrations.DeleteModel( - name='Use654567', - ), - ] diff --git a/db/migrations/0004_alter_order_created_at.py b/db/migrations/0004_alter_order_created_at.py deleted file mode 100644 index f9d0f01b5..000000000 --- a/db/migrations/0004_alter_order_created_at.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 16:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0003_delete_use654567'), - ] - - operations = [ - migrations.AlterField( - model_name='order', - name='created_at', - field=models.DateTimeField(), - ), - ] diff --git a/db/migrations/0005_alter_order_created_at.py b/db/migrations/0005_alter_order_created_at.py deleted file mode 100644 index 36ec2a7b9..000000000 --- a/db/migrations/0005_alter_order_created_at.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 16:38 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0004_alter_order_created_at'), - ] - - operations = [ - migrations.AlterField( - model_name='order', - name='created_at', - field=models.DateTimeField(auto_now_add=True), - ), - ] diff --git a/db/migrations/0006_ticket_unique_order_row_seat_order_session.py b/db/migrations/0006_ticket_unique_order_row_seat_order_session.py deleted file mode 100644 index 06b2ea3af..000000000 --- a/db/migrations/0006_ticket_unique_order_row_seat_order_session.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.2 on 2023-10-29 18:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0005_alter_order_created_at'), - ] - - operations = [ - migrations.AddConstraint( - model_name='ticket', - constraint=models.UniqueConstraint(fields=('row', 'seat', 'movie_session'), name='unique_order_row_seat_order_session'), - ), - ] diff --git a/db/migrations/0007_alter_order_options_moviesession_row_and_more.py b/db/migrations/0007_alter_order_options_moviesession_row_and_more.py deleted file mode 100644 index b0f23462c..000000000 --- a/db/migrations/0007_alter_order_options_moviesession_row_and_more.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.0.2 on 2023-11-07 15:14 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('db', '0006_ticket_unique_order_row_seat_order_session'), - ] - - operations = [ - migrations.AlterModelOptions( - name='order', - options={'ordering': ['-created_at']}, - ), - migrations.AddField( - model_name='moviesession', - name='row', - field=models.IntegerField(null=True), - ), - migrations.AddField( - model_name='moviesession', - name='seat', - field=models.IntegerField(null=True), - ), - ] diff --git a/db/models.py b/db/models.py index 8d14991b5..5f44eabf4 100644 --- a/db/models.py +++ b/db/models.py @@ -1,7 +1,7 @@ -from django.db import models -from django.contrib.contenttypes.models import ContentType -from django.contrib.auth.models import User +from django.conf import settings +from django.contrib.auth.models import AbstractUser from django.core.exceptions import ValidationError +from django.db import models class Genre(models.Model): @@ -43,8 +43,6 @@ def __str__(self) -> str: class MovieSession(models.Model): - row = models.IntegerField(null=True) - seat = models.IntegerField(null=True) show_time = models.DateTimeField() cinema_hall = models.ForeignKey( to=CinemaHall, on_delete=models.CASCADE, related_name="movie_sessions" @@ -54,12 +52,16 @@ class MovieSession(models.Model): ) def __str__(self) -> str: - return f"{self.movie.title} {str(self.show_time)} {self.cinema_hall.rows} {self.cinema_hall.seats_in_row}" + return f"{self.movie.title} {self.show_time} {self.cinema_hall.rows} {self.cinema_hall.seats_in_row}" class Order(models.Model): created_at = models.DateTimeField(auto_now_add=True) - user = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='orders') + user = models.ForeignKey( + to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="orders" + ) class Meta: ordering = ["-created_at"] @@ -67,23 +69,35 @@ class Meta: def __str__(self) -> str: return str(self.created_at) + class Ticket(models.Model): - movie_session = models.ForeignKey(to=MovieSession, on_delete=models.CASCADE) + movie_session = models.ForeignKey( + to=MovieSession, + on_delete=models.CASCADE + ) order = models.ForeignKey(Order, on_delete=models.CASCADE) row = models.IntegerField() seat = models.IntegerField() - def clean(self): - max_row = self.movie_session.cinema_hall.rows # Отримати максимальне значення row - max_seat = self.movie_session.cinema_hall.seats_in_row # Отримати максимальне значення seat + def clean(self) -> None: + max_row = self.movie_session.cinema_hall.rows + max_seat = self.movie_session.cinema_hall.seats_in_row if self.row > max_row: - raise ValidationError({'row': f'row number must be in available range: (1, rows): (1, {max_row})'}) + raise ValidationError( + {"row": + f"row number must be in available range: " + f"(1, rows): (1, {max_row})"} + ) if self.seat > max_seat: - raise ValidationError({'seat': f'seat number must be in available range: (1, seats_in_row): (1, {max_seat})'}) + raise ValidationError( + {"seat": f"seat number must " + f"be in available range: (1, seats_in_row): " + f"(1, {max_seat})"} + ) - def save(self, *args, **kwargs): + def save(self, *args, **kwargs) -> None: self.full_clean() super().save(*args, **kwargs) @@ -92,18 +106,18 @@ class Meta: models.UniqueConstraint( fields=["row", "seat", "movie_session"], name="unique_order_row_seat_order_session" - ) + ) ] - def __str__(self) -> str: - return f"Matrix 2019-08-19 20:30:00 (row: {self.row}, seat: {self.seat})" - + def __str__(self) -> str : + return ( + f"Matrix 2019-08-19 20:30:00 " # noqa + f"(row: {self.row}, " + f"seat: {self.seat})" + ) -class User(models.Model): - movie_session = models.ForeignKey(to=MovieSession, on_delete=models.CASCADE) - order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='user_orders') - row = models.IntegerField() - seat = models.IntegerField() - def __str__(self) -> str: - return f"Ticket: {self.order}, (row: {self.row}, seat: {self.seat})" +class User(AbstractUser): + USERNAME_FIELD = "username" + REQUIRED_FIELDS = [] + pass diff --git a/services/movie.py b/services/movie.py index 6198bcc67..9baf1c021 100644 --- a/services/movie.py +++ b/services/movie.py @@ -6,7 +6,7 @@ def get_movies( genres_ids: list[int] = None, actors_ids: list[int] = None, - title=None, + title: str = None, ) -> QuerySet: queryset = Movie.objects.all() @@ -17,8 +17,7 @@ def get_movies( queryset = queryset.filter(actors__id__in=actors_ids) if title: - # фільтрувати фільми за назвою, якщо аргумент `title` переданий - return Movie.objects.filter(title__icontains=title) + return queryset.filter(title__icontains=title) return queryset diff --git a/services/movie_session.py b/services/movie_session.py index 73eb4ac23..074b098f3 100644 --- a/services/movie_session.py +++ b/services/movie_session.py @@ -44,9 +44,9 @@ def delete_movie_session_by_id(session_id: int) -> None: MovieSession.objects.get(id=session_id).delete() -def get_taken_seats(movie_session_id): +def get_taken_seats(movie_session_id: int) -> list: taken_seats = [] tickets = Ticket.objects.filter(movie_session_id=movie_session_id) for ticket in tickets: taken_seats.append({"row": ticket.row, "seat": ticket.seat}) - return taken_seats \ No newline at end of file + return taken_seats diff --git a/services/order.py b/services/order.py index 4c3f8b965..9c1790acb 100644 --- a/services/order.py +++ b/services/order.py @@ -1,14 +1,18 @@ -import distutils -from datetime import date +import datetime + from db.models import Order from django.db import transaction from typing import List -from db.models import MovieSession, User, Ticket -from django.contrib.auth.models import User +from db.models import MovieSession, Ticket +from db.models import User @transaction.atomic -def create_order(tickets: List[dict], username, date=None): +def create_order( + tickets: List[dict], + username: str, + date: datetime = None +) -> None: user, created = User.objects.get_or_create(username=username) order, created = Order.objects.get_or_create(user=user) if date is not None: @@ -18,20 +22,20 @@ def create_order(tickets: List[dict], username, date=None): row = ticket_data.get("row") seat = ticket_data.get("seat") movie_session = MovieSession.objects.get(pk=1) - ticket, created = Ticket.objects.get_or_create(row=row, seat=seat, movie_session=movie_session, order=order) + ticket, created = Ticket.objects.get_or_create( + row=row, + seat=seat, + movie_session=movie_session, + order=order + ) ticket.order = order ticket.save() - # if date is not None: - # Order.objects.update_or_create(user=username, created_at=date) - # Ticket.objects.update_or_create(row=row, seat=seat, movie_session=movie_session) - # else: - # Order.objects.update_or_create(user=username) - # Ticket.objects.update_or_create(row=row, seat=seat, movie_session=movie_session) - #return -def get_orders(username=None): +def get_orders(username: str = None) -> list: if username is not None: - return Order.objects.filter(user__username=username).order_by("created_at") + return Order.objects.filter( + user__username=username).order_by("created_at" + ) elif username is None: return Order.objects.all().order_by("-created_at") diff --git a/services/user.py b/services/user.py index be587f855..5d6d67b99 100644 --- a/services/user.py +++ b/services/user.py @@ -1,10 +1,23 @@ from django.contrib.auth.hashers import make_password -from django.contrib.auth.models import User +from db.models import User -def create_user( username, password, user_id=None, email=None, first_name=None, last_name=None): +def create_user( + username: str, + password: str, + user_id: int = None, + email: str = None, + first_name: str = None, + last_name: str = None +) -> None: try: - user, created = User.objects.update_or_create(id=user_id, defaults={'username': username, 'password': make_password(password)}) + user, created = User.objects.update_or_create( + id=user_id, + defaults=( + {"username": username, + "password": make_password(password)} + ) + ) if email is not None: user.email = email if first_name is not None: @@ -17,10 +30,18 @@ def create_user( username, password, user_id=None, email=None, first_name=None, return None -def get_user(user_id): +def get_user(user_id: int) -> int: return User.objects.get(id=user_id) -def update_user(user_id, username=None, password=None, email=None, first_name=None, last_name=None): + +def update_user( + user_id: int, + username: str = None, + password: str = None, + email: str = None, + first_name: str = None, + last_name: str = None +) -> None: try: user = User.objects.get(id=user_id) except User.DoesNotExist: @@ -39,4 +60,3 @@ def update_user(user_id, username=None, password=None, email=None, first_name=No user.save() return user - diff --git a/settings.py b/settings.py index d02fb68ef..4656ed778 100644 --- a/settings.py +++ b/settings.py @@ -24,9 +24,9 @@ USE_TZ = False INSTALLED_APPS = [ - "db", "django.contrib.auth", "django.contrib.contenttypes", + "db", ] -AUTH_USER_MODEL = "auth.User" +AUTH_USER_MODEL = "db.User"