сделал процедуру оформления заказа и покупки билетов
This commit is contained in:
parent
72e025bb34
commit
be03d5c234
@ -4,3 +4,4 @@ from django.apps import AppConfig
|
||||
class FilmsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'films'
|
||||
verbose_name = 'Фильмы'
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
@ -117,4 +117,7 @@
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 1.2vw;
|
||||
}
|
||||
.disabled {
|
||||
background-color: #0d1d3a !important;
|
||||
}
|
||||
@ -34,11 +34,19 @@
|
||||
<td class="row_number_cell cell">Ряд {{ forloop.counter }}</td>
|
||||
{% for _ in row.column_count|get_range %}
|
||||
<td class="cell">
|
||||
<label class="film_session disabled">
|
||||
<input type="checkbox" name="selected_seats"
|
||||
value="[{{ forloop.counter }}, {{ row.row_number }}]" class="seat_checkbox"
|
||||
disabled>
|
||||
<span class="seat_number">{{ forloop.counter }}</span>
|
||||
</label>
|
||||
{% else %}
|
||||
<label class="film_session">
|
||||
<input type="checkbox" name="selected_seats"
|
||||
value="[{{ forloop.counter }}, {{ row.row_number }}]" class="seat_checkbox">
|
||||
<span class="seat_number">{{ forloop.counter }}</span>
|
||||
</label>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
|
||||
@ -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,
|
||||
]
|
||||
|
||||
@ -4,3 +4,4 @@ from django.apps import AppConfig
|
||||
class TicketsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'tickets'
|
||||
verbose_name = 'Билеты'
|
||||
|
||||
@ -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="Дата и время оформления заказа",
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -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,
|
||||
|
||||
@ -4,3 +4,4 @@ from django.apps import AppConfig
|
||||
class TimetableConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'timetable'
|
||||
verbose_name = 'Сеансы и залы'
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -4,3 +4,4 @@ from django.apps import AppConfig
|
||||
class UsersConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'users'
|
||||
verbose_name = 'Пользователи'
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user