начал делать форму для выбора нескольких мест
This commit is contained in:
parent
c08a38f313
commit
0c7343b5a3
30
CineSync/films/migrations/0005_film_age_limit.py
Normal file
30
CineSync/films/migrations/0005_film_age_limit.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Generated by Django 4.2 on 2024-04-20 12:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("films", "0004_film_image"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="film",
|
||||||
|
name="age_limit",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
["0+", "0+"],
|
||||||
|
["6+", "0+"],
|
||||||
|
["12+", "12+"],
|
||||||
|
["16+", "16+"],
|
||||||
|
["18+", "18+"],
|
||||||
|
],
|
||||||
|
default="12+",
|
||||||
|
help_text="Возрастное ограничение",
|
||||||
|
max_length=3,
|
||||||
|
),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -117,6 +117,19 @@ class Film(Model):
|
|||||||
help_text='Жанры фильма',
|
help_text='Жанры фильма',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
age_limit = CharField(
|
||||||
|
help_text='Возрастное ограничение',
|
||||||
|
max_length=3,
|
||||||
|
null=False,
|
||||||
|
choices=(
|
||||||
|
['0+', '0+'],
|
||||||
|
['6+', '0+'],
|
||||||
|
['12+', '12+'],
|
||||||
|
['16+', '16+'],
|
||||||
|
['18+', '18+'],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def get_image_300x300(self):
|
def get_image_300x300(self):
|
||||||
return sorl.thumbnail.get_thumbnail(
|
return sorl.thumbnail.get_thumbnail(
|
||||||
self.image,
|
self.image,
|
||||||
|
|||||||
@ -3,4 +3,12 @@
|
|||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
background-color: #0d1d3a;
|
background-color: #0d1d3a;
|
||||||
|
}
|
||||||
|
html::-webkit-scrollbar {
|
||||||
|
width: 0.8vw;
|
||||||
|
}
|
||||||
|
html::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #eaeaea;
|
||||||
|
border-radius: 5vw;
|
||||||
|
border: 4px solid #0d1d3a;
|
||||||
}
|
}
|
||||||
@ -17,4 +17,12 @@
|
|||||||
height: 35vw !important;
|
height: 35vw !important;
|
||||||
width: 25vw !important;
|
width: 25vw !important;
|
||||||
border-radius: 3vw;
|
border-radius: 3vw;
|
||||||
|
}
|
||||||
|
.film_card_column::-webkit-scrollbar {
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
.film_card_column::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #0d1d3a;
|
||||||
|
border-radius: 5vw;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
}
|
}
|
||||||
@ -1,35 +1,30 @@
|
|||||||
.seats_card {
|
.seats_card {
|
||||||
|
margin-left: 27%;
|
||||||
|
margin-right: 27%;
|
||||||
|
margin-top: 2vw;
|
||||||
|
margin-bottom: 5vw;
|
||||||
background-color: #eaeaea;
|
background-color: #eaeaea;
|
||||||
border-radius: 3vw;
|
border-radius: 3vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
width: 46%;
|
||||||
width: 50%;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 2vw;
|
|
||||||
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.card_body {
|
.seat_checkbox {
|
||||||
width: 80%;
|
display: none;
|
||||||
}
|
}
|
||||||
.line {
|
.seat_checkbox:checked + .seat_number {
|
||||||
width: 30%;
|
color: #ffffff;
|
||||||
height: 0.5vw;
|
|
||||||
background-color: black;
|
|
||||||
position: absolute;
|
|
||||||
top: 70%;
|
|
||||||
border-radius: 3vw;
|
|
||||||
margin-left: 5%;
|
|
||||||
margin-top: 8vw;
|
|
||||||
}
|
}
|
||||||
h6 {
|
.selected {
|
||||||
text-align: center;
|
background-color: #0d1d3a;
|
||||||
margin-top: 0.4vw;
|
}
|
||||||
|
.selected:hover {
|
||||||
|
background-color: #0d1d3a;
|
||||||
}
|
}
|
||||||
.seat_number {
|
.seat_number {
|
||||||
width: 1vw;
|
width: 1vw;
|
||||||
@ -54,29 +49,35 @@ h6 {
|
|||||||
border-radius: 3vw;
|
border-radius: 3vw;
|
||||||
}
|
}
|
||||||
.film_info_block {
|
.film_info_block {
|
||||||
margin-right: 25%;
|
margin-top: 5vw;
|
||||||
margin-left: 25%;
|
margin-right: 27%;
|
||||||
width: 50%;
|
margin-left: 27%;
|
||||||
|
width: 46%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
|
height: 20vw;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.film_info_text_block {
|
.film_info_text_block {
|
||||||
height: 20vw;
|
height: 20vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
justify-content: space-evenly;
|
justify-content: flex-start;
|
||||||
margin: 2vw;
|
align-items: flex-start;
|
||||||
|
margin-left: 1vw;
|
||||||
}
|
}
|
||||||
.film_info_text {
|
.film_info_text, .film_info_description {
|
||||||
color: #eaeaea;
|
color: #eaeaea;
|
||||||
}
|
}
|
||||||
|
.film_info_description {
|
||||||
|
max-height: 9.9vw;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
.cell {
|
.cell {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
|
||||||
.cell {
|
|
||||||
height: 4vw;
|
height: 4vw;
|
||||||
width: 3.5vw;
|
width: 3.5vw;
|
||||||
}
|
}
|
||||||
@ -84,4 +85,20 @@ h6 {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
width: 3vw;
|
||||||
|
}
|
||||||
|
.seats_card::-webkit-scrollbar {
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
.seats_card::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #0d1d3a;
|
||||||
|
border-radius: 5vw;
|
||||||
|
border: 1px solid #eaeaea;
|
||||||
|
}
|
||||||
|
.film_info_description::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
.film_info_description::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #eaeaea;
|
||||||
|
border-radius: 5vw;
|
||||||
}
|
}
|
||||||
10
CineSync/static/js/timetable/session.js
Normal file
10
CineSync/static/js/timetable/session.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
document.querySelectorAll('.seat_checkbox').forEach(function(checkbox) {
|
||||||
|
checkbox.addEventListener('change', function() {
|
||||||
|
var filmSession = checkbox.closest('.film_session');
|
||||||
|
if (checkbox.checked) {
|
||||||
|
filmSession.classList.add('selected'); // Добавляем класс, если чекбокс выбран
|
||||||
|
} else {
|
||||||
|
filmSession.classList.remove('selected'); // Удаляем класс, если чекбокс не выбран
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
0
CineSync/templates/tickets/ticket_details.html
Normal file
0
CineSync/templates/tickets/ticket_details.html
Normal file
@ -14,30 +14,35 @@
|
|||||||
<h1 class="film_info_text">{{ session.film.name }}</h1>
|
<h1 class="film_info_text">{{ session.film.name }}</h1>
|
||||||
<p class="film_info_text">{{ session.auditorium.number }}</p>
|
<p class="film_info_text">{{ session.auditorium.number }}</p>
|
||||||
<p class="film_info_text">{{ session.start_datetime }}</p>
|
<p class="film_info_text">{{ session.start_datetime }}</p>
|
||||||
</div>
|
<p class="film_info_description">{{ session.film.description }}</p>
|
||||||
</div>
|
<div class="tags_block">
|
||||||
<div class="seats_card" style="height: {{ height }}vw;">
|
{% for genre in session.film.genres.all %}
|
||||||
<div class="card_body">
|
<div class="badge text-bg-secondary genre">{{genre.name}}</div>
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
{% for row in session.auditorium.row_count|get_range %}
|
|
||||||
<tr>
|
|
||||||
<td class="row_number_cell cell">{{ row }}</td>
|
|
||||||
{% for seat in seats %}
|
|
||||||
<td class="cell">
|
|
||||||
<a class="film_session">
|
|
||||||
<span class="seat_number">{{ seat.row_number }}</span>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div>
|
|
||||||
<button class="btn btn-primary buy_btn">Купить билет</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="seats_card" style="height: {{ height }}vw;">
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
{% for row in session.auditorium.row_count|get_range %}
|
||||||
|
<tr>
|
||||||
|
<td class="row_number_cell cell">Ряд {{ row }}</td>
|
||||||
|
{% for seat in seats %}
|
||||||
|
<td class="cell">
|
||||||
|
<label class="film_session">
|
||||||
|
<input type="checkbox" class="seat_checkbox" value="{{ seat.row_number }}">
|
||||||
|
<span class="seat_number">{{ seat.row_number }}</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div>
|
||||||
|
<button class="btn btn-primary buy_btn">Купить билет</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="{% static 'js/timetable/session.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.2 on 2024-04-20 12:53
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("tickets", "0004_rename_user_ticket_profile"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="ticket",
|
||||||
|
options={"verbose_name": "Билет", "verbose_name_plural": "Билеты"},
|
||||||
|
),
|
||||||
|
migrations.AlterModelTable(
|
||||||
|
name="ticket",
|
||||||
|
table="tickets_ticket",
|
||||||
|
),
|
||||||
|
]
|
||||||
12
CineSync/timetable/forms.py
Normal file
12
CineSync/timetable/forms.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from django import forms
|
||||||
|
|
||||||
|
from timetable.models import Auditorium, Row
|
||||||
|
|
||||||
|
|
||||||
|
class SeatSelectionForm(forms.Form):
|
||||||
|
def __init__(self, auditorium: Auditorium):
|
||||||
|
super().__init__()
|
||||||
|
self.selected_seats = forms.MultipleChoiceField(
|
||||||
|
widget=forms.CheckboxSelectMultiple,
|
||||||
|
choices=[(str(seat.id), seat.row_number) for seat in auditorium.rows.all()],
|
||||||
|
)
|
||||||
@ -3,9 +3,9 @@ from datetime import date
|
|||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
from timetable.models import FilmSession, Row
|
|
||||||
|
|
||||||
from timetable.models import FilmSession
|
from timetable.models import FilmSession, Row
|
||||||
|
from timetable.forms import SeatSelectionForm
|
||||||
|
|
||||||
|
|
||||||
def timetable_view(request):
|
def timetable_view(request):
|
||||||
@ -45,7 +45,11 @@ def session_view(request, sess_id):
|
|||||||
FilmSession.objects.all(),
|
FilmSession.objects.all(),
|
||||||
id=sess_id,
|
id=sess_id,
|
||||||
)
|
)
|
||||||
height = session.auditorium.row_count * 6
|
height = round(session.auditorium.row_count * 4 + 7)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
print(request.data)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'session': session,
|
'session': session,
|
||||||
'seats': Row.objects.filter(auditorium_id=session.auditorium.id),
|
'seats': Row.objects.filter(auditorium_id=session.auditorium.id),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user