diff --git a/CineSync/films/apps.py b/CineSync/films/apps.py index 10d6934..4b4f46b 100644 --- a/CineSync/films/apps.py +++ b/CineSync/films/apps.py @@ -4,3 +4,4 @@ from django.apps import AppConfig class FilmsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'films' + verbose_name = 'Фильмы' diff --git a/CineSync/home/models.py b/CineSync/home/models.py deleted file mode 100644 index 71a8362..0000000 --- a/CineSync/home/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/CineSync/static/css/timetable/session.css b/CineSync/static/css/timetable/session.css index 4235f5f..8bf2b8e 100644 --- a/CineSync/static/css/timetable/session.css +++ b/CineSync/static/css/timetable/session.css @@ -117,4 +117,7 @@ width: 100%; text-align: center; font-size: 1.2vw; +} +.disabled { + background-color: #0d1d3a !important; } \ No newline at end of file diff --git a/CineSync/templates/timetable/session.html b/CineSync/templates/timetable/session.html index 758a2d1..55cbb57 100644 --- a/CineSync/templates/timetable/session.html +++ b/CineSync/templates/timetable/session.html @@ -34,11 +34,19 @@ Ряд {{ forloop.counter }} {% for _ in row.column_count|get_range %} + + {% else %} + {% endif %} {% endfor %} diff --git a/CineSync/tickets/admin.py b/CineSync/tickets/admin.py index 8c38f3f..22be9df 100644 --- a/CineSync/tickets/admin.py +++ b/CineSync/tickets/admin.py @@ -1,3 +1,18 @@ from django.contrib import admin -# Register your models here. +from tickets.models import Ticket, Order + + +class TicketAdminInline(admin.StackedInline): + model = Ticket + + +@admin.register(Order) +class AuditoriumAdmin(admin.ModelAdmin): + list_display = [ + Order.profile.field.name, + Order.datetime_order.field.name, + ] + inlines = [ + TicketAdminInline, + ] diff --git a/CineSync/tickets/apps.py b/CineSync/tickets/apps.py index 45a7d76..d3c32fa 100644 --- a/CineSync/tickets/apps.py +++ b/CineSync/tickets/apps.py @@ -4,3 +4,4 @@ from django.apps import AppConfig class TicketsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'tickets' + verbose_name = 'Билеты' diff --git a/CineSync/tickets/migrations/0007_alter_order_datetime_order.py b/CineSync/tickets/migrations/0007_alter_order_datetime_order.py new file mode 100644 index 0000000..b1db2dc --- /dev/null +++ b/CineSync/tickets/migrations/0007_alter_order_datetime_order.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2 on 2024-04-20 18:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tickets", "0006_remove_ticket_profile_remove_ticket_session_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="order", + name="datetime_order", + field=models.DateTimeField( + help_text="Дата и время оформления заказа", + verbose_name="Дата и время оформления заказа", + ), + ), + ] diff --git a/CineSync/tickets/models.py b/CineSync/tickets/models.py index b4190f4..78dd5d5 100644 --- a/CineSync/tickets/models.py +++ b/CineSync/tickets/models.py @@ -1,10 +1,16 @@ -from django.db.models import ForeignKey, CASCADE, Model, IntegerField, DateField +from django.db.models import ForeignKey, CASCADE, Model, IntegerField, DateTimeField, Manager from django.core.validators import MinValueValidator from timetable.models import FilmSession from users.models import Profile +class TicketManager(Manager): + def get_tickets_for_session(self, session_id): + tickets = super().get_queryset().filter(order__session_id=session_id) + return tickets + + class Order(Model): session = ForeignKey( FilmSession, @@ -20,7 +26,7 @@ class Order(Model): related_query_name='orders', ) - datetime_order = DateField( + datetime_order = DateTimeField( verbose_name='Дата и время оформления заказа', help_text='Дата и время оформления заказа', ) @@ -32,6 +38,8 @@ class Order(Model): class Ticket(Model): + objects = TicketManager() + order = ForeignKey( Order, on_delete=CASCADE, diff --git a/CineSync/timetable/apps.py b/CineSync/timetable/apps.py index f3abe50..793ce85 100644 --- a/CineSync/timetable/apps.py +++ b/CineSync/timetable/apps.py @@ -4,3 +4,4 @@ from django.apps import AppConfig class TimetableConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'timetable' + verbose_name = 'Сеансы и залы' diff --git a/CineSync/timetable/forms.py b/CineSync/timetable/forms.py index 886d4e6..f495437 100644 --- a/CineSync/timetable/forms.py +++ b/CineSync/timetable/forms.py @@ -24,6 +24,6 @@ class SeatSelectionForm(forms.Form): def clean_selected_seats(self): selected_seats = self.cleaned_data['selected_seats'] - if list[str] is type(self.cleaned_data): + if isinstance(selected_seats, list) and all(isinstance(item, str) for item in selected_seats): selected_seats = [loads(field) for field in selected_seats] return selected_seats diff --git a/CineSync/timetable/models.py b/CineSync/timetable/models.py index 9744ada..8497903 100644 --- a/CineSync/timetable/models.py +++ b/CineSync/timetable/models.py @@ -112,6 +112,9 @@ class FilmSession(Model): related_query_name='sessions', ) + def __str__(self): + return f'{self.film.name} - {str(self.start_datetime)} - {self.auditorium}' + def save(self, *args, **kwargs): if self.start_datetime and self.film.duration: self.end_datetime = self.start_datetime + timedelta(minutes=self.film.duration) diff --git a/CineSync/timetable/views.py b/CineSync/timetable/views.py index 519ae99..5383333 100644 --- a/CineSync/timetable/views.py +++ b/CineSync/timetable/views.py @@ -1,13 +1,16 @@ import datetime from datetime import date -from django.db.models import Max +from django.contrib.auth.decorators import login_required +from django.db import transaction from django.http import HttpResponse -from django.shortcuts import render, get_object_or_404 +from django.shortcuts import render, get_object_or_404, redirect +from django.urls import reverse +from django.utils import timezone from timetable.models import FilmSession, Row - from timetable.forms import SeatSelectionForm +from tickets.models import Order, Ticket def timetable_view(request): @@ -42,6 +45,7 @@ def timetable_view(request): ) +@login_required def session_view(request, sess_id): session = get_object_or_404( FilmSession.objects.all(), @@ -49,11 +53,30 @@ def session_view(request, sess_id): ) height = round(session.auditorium.rows.count() * 4 + 7) + tickets = Ticket.objects.get_tickets_for_session(session.pk) + occupied_seats = [f'{str(ticket.column_number)}{str(ticket.row_number)}' for ticket in tickets] + if request.method == 'POST': form = SeatSelectionForm(request.POST, auditorium=session.auditorium) if form.is_valid(): - selected_seats = form.clean_selected_seats() - # return redirect('куда-то-перенаправление-после-выбора-мест') + with transaction.atomic(): + selected_seats = form.clean_selected_seats() + user_profile = request.user.profile + + order = Order.objects.create( + session=session, + profile=user_profile, + datetime_order=timezone.now(), + ) + + for seat in selected_seats: + Ticket.objects.create( + order=order, + row_number=seat[0], + column_number=seat[1], + ) + + return redirect(reverse('home:homepage')) else: form = SeatSelectionForm(auditorium=session.auditorium) @@ -61,6 +84,7 @@ def session_view(request, sess_id): 'session': session, 'height': height, 'form': form, + 'occupied_seats': occupied_seats, } template = 'timetable/session.html' return render(request, template, context) diff --git a/CineSync/users/apps.py b/CineSync/users/apps.py index 72b1401..9bd2bee 100644 --- a/CineSync/users/apps.py +++ b/CineSync/users/apps.py @@ -4,3 +4,4 @@ from django.apps import AppConfig class UsersConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'users' + verbose_name = 'Пользователи' diff --git a/CineSync/users/models.py b/CineSync/users/models.py index 35de351..bc49b50 100644 --- a/CineSync/users/models.py +++ b/CineSync/users/models.py @@ -41,6 +41,9 @@ class Profile(Model): related_query_name='profiles', ) + def __str__(self): + return f'{self.user} - {self.user.last_name} {self.user.first_name}' + def get_image_x300(self): return get_thumbnail( self.image,