поправил форматирование

This commit is contained in:
Андрей Дувакин 2024-04-22 22:54:03 +05:00
parent 84e66e7978
commit feb1493ecd
38 changed files with 215 additions and 152 deletions

View File

@ -1,7 +1,7 @@
[flake8] [flake8]
max-line-length = 80 max-line-length = 80
import-order-style = google import-order-style = google
application-import-names = timetable, tickets, home, films application-import-names = timetable, tickets, home, films, users
exclude = exclude =
.git, .git,
__pycache__, __pycache__,

View File

@ -1,5 +1,6 @@
import os import os
from pathlib import Path from pathlib import Path
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
@ -83,21 +84,25 @@ DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3',
} },
} }
AUTH_PASSWORD_VALIDATORS = [ AUTH_PASSWORD_VALIDATORS = [
{ {
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 'NAME': 'django.contrib.auth.'
'password_validation.UserAttributeSimilarityValidator',
}, },
{ {
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'NAME': 'django.contrib.auth.'
'password_validation.MinimumLengthValidator',
}, },
{ {
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 'NAME': 'django.contrib.auth.'
'password_validation.CommonPasswordValidator',
}, },
{ {
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 'NAME': 'django.contrib.auth.'
'password_validation.NumericPasswordValidator',
}, },
] ]

View File

@ -10,15 +10,15 @@ urlpatterns = [
path('films/', include('films.urls'), name='films'), path('films/', include('films.urls'), name='films'),
path('timetable/', include('timetable.urls'), name='timetable'), path('timetable/', include('timetable.urls'), name='timetable'),
path('tickets/', include('tickets.urls'), name='tickets'), path('tickets/', include('tickets.urls'), name='tickets'),
path("auth/", include("users.urls"), name="auth"), path('auth/', include('users.urls'), name='auth'),
path("auth/", include("django.contrib.auth.urls"), name="auth"), path('auth/', include('django.contrib.auth.urls'), name='auth'),
] ]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static( urlpatterns += static(
settings.MEDIA_URL, settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT, document_root=settings.MEDIA_ROOT,
) )
if settings.DEBUG: if settings.DEBUG:
import debug_toolbar import debug_toolbar

View File

@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from films.models import Film, Genre, Actor, Director, Country from films.models import Actor, Country, Director, Film, Genre
@admin.register(Film) @admin.register(Film)
@ -13,7 +13,7 @@ class FilmAdmin(admin.ModelAdmin):
'get_image', 'get_image',
] ]
readonly_fields = ("get_image",) readonly_fields = ('get_image',)
filter_horizontal = [ filter_horizontal = [
Film.genres.field.name, Film.genres.field.name,
@ -28,7 +28,7 @@ class FilmAdmin(admin.ModelAdmin):
def get_image(self, obj): def get_image(self, obj):
return mark_safe( return mark_safe(
f"<img src='{obj.image_tmb()}' width='50' height='50'", f'<img src="{obj.image_tmb()}" width="50" height="50"',
) )

View File

@ -62,14 +62,17 @@ class Migration(migrations.Migration):
"duration", "duration",
models.IntegerField( models.IntegerField(
help_text="Продолжительность фильма (в минутах)", help_text="Продолжительность фильма (в минутах)",
validators=[django.core.validators.MinValueValidator(0)], validators=[
django.core.validators.MinValueValidator(0)
],
verbose_name="Продолжительность", verbose_name="Продолжительность",
), ),
), ),
( (
"release_date", "release_date",
models.DateField( models.DateField(
help_text="Дата выхода фильма", verbose_name="Дата релиза" help_text="Дата выхода фильма",
verbose_name="Дата релиза",
), ),
), ),
( (

View File

@ -25,7 +25,9 @@ class Migration(migrations.Migration):
( (
"first_name", "first_name",
models.CharField( models.CharField(
help_text="Имя актера", max_length=100, verbose_name="Имя" help_text="Имя актера",
max_length=100,
verbose_name="Имя",
), ),
), ),
( (
@ -85,7 +87,9 @@ class Migration(migrations.Migration):
( (
"first_name", "first_name",
models.CharField( models.CharField(
help_text="Имя режиссера", max_length=100, verbose_name="Имя" help_text="Имя режиссера",
max_length=100,
verbose_name="Имя",
), ),
), ),
( (

View File

@ -6,7 +6,10 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("films", "0006_actor_country_director_film_actors_film_countries_and_more"), (
"films",
"0006_actor_country_director_film_actors_film_countries_and_more",
),
] ]
operations = [ operations = [

View File

@ -1,15 +1,16 @@
import time
from datetime import timedelta from datetime import timedelta
import time
import sorl
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db.models import ( from django.db.models import (
Model,
CharField, CharField,
IntegerField,
DateField, DateField,
ImageField,
IntegerField,
Manager,
ManyToManyField, ManyToManyField,
Manager, ImageField, Min, Min,
Model,
) )
from django.utils import timezone from django.utils import timezone
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -18,36 +19,51 @@ from sorl.thumbnail import get_thumbnail
class FilmManager(Manager): class FilmManager(Manager):
def released(self): def released(self):
return super().get_queryset().filter( return (
release_date__lt=timezone.now(), super()
.get_queryset()
.filter(
release_date__lt=timezone.now(),
)
) )
def will_be_shown(self): def will_be_shown(self):
current_datetime = timezone.now() current_datetime = timezone.now()
films_with_sessions = super().get_queryset().filter( return (
sessions__start_datetime__gte=current_datetime, super()
).annotate( .get_queryset()
nearest_session=Min('sessions__start_datetime') .filter(
).order_by('nearest_session') sessions__start_datetime__gte=current_datetime,
)
return films_with_sessions .annotate(nearest_session=Min('sessions__start_datetime'))
.order_by('nearest_session')
)
def on_main(self): def on_main(self):
current_datetime = timezone.now() current_datetime = timezone.now()
end_datetime = current_datetime + timedelta(days=5) end_datetime = current_datetime + timedelta(days=5)
films_with_sessions = super().get_queryset().filter( queryset = super().get_queryset()
sessions__start_datetime__gte=current_datetime, films_with_sessions = (
sessions__start_datetime__lte=end_datetime, queryset.filter(
).exclude(image=None).distinct().only( sessions__start_datetime__gte=current_datetime,
Film.name.field.name, sessions__start_datetime__lte=end_datetime,
Film.image.field.name, )
Film.description.field.name, .exclude(image=None)
.distinct()
.only(
Film.name.field.name,
Film.image.field.name,
Film.description.field.name,
)
) )
if films_with_sessions.count() > 5: if films_with_sessions.count() > 5:
films_with_sessions = films_with_sessions[:5] films_with_sessions = films_with_sessions[:5]
elif films_with_sessions.count() > 0: elif films_with_sessions.count() > 0:
films_with_sessions = films_with_sessions[:films_with_sessions.count()] films_with_sessions = films_with_sessions[
: films_with_sessions.count()
]
return films_with_sessions return films_with_sessions
@ -209,23 +225,23 @@ class Film(Model):
) )
def get_image_300x300(self): def get_image_300x300(self):
return sorl.thumbnail.get_thumbnail( return get_thumbnail(
self.image, self.image,
"300x300", '300x300',
crop="center", crop='center',
quality=51, quality=51,
) )
def image_tmb(self): def image_tmb(self):
if self.image: if self.image:
tag = f"{self.get_image_300x300().url}" tag = f'{self.get_image_300x300().url}'
return mark_safe(tag) return mark_safe(tag)
return "Нет изорбражения" return 'Нет изорбражения'
image_tmb.field_name = "image_tmb" image_tmb.field_name = 'image_tmb'
image_tmb.allow_tags = True image_tmb.allow_tags = True
image_tmb.short_description = "Превью" image_tmb.short_description = 'Превью'
class Meta: class Meta:
db_table = 'films_films' db_table = 'films_films'

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,9 +1,9 @@
from django.urls import path from django.urls import path
from films.views import films_list, film_details from films.views import film_details, films_list
app_name = 'films' app_name = 'films'
urlpatterns = [ urlpatterns = [
path('', films_list, name='main'), path('', films_list, name='main'),
path('<int:film_id>/', film_details, name='film_details') path('<int:film_id>/', film_details, name='film_details'),
] ]

View File

@ -1,5 +1,5 @@
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import get_object_or_404, render
from films.models import Film from films.models import Film
from timetable.models import FilmSession from timetable.models import FilmSession
@ -19,16 +19,21 @@ def film_details(request: HttpResponse, film_id: int) -> HttpResponse:
Film.objects.released(), Film.objects.released(),
id=film_id, id=film_id,
) )
film_sessions = FilmSession.objects.nearest_timetable().filter(film_id=film_id) film_sessions = FilmSession.objects.nearest_timetable().filter(
film_id=film_id,
)
sessions_by_date_and_film = {} sessions_by_date_and_film = {}
for session in film_sessions: for session in film_sessions:
session_date = session.start_datetime.date() session_date = session.start_datetime.date()
if session_date not in sessions_by_date_and_film: if session_date not in sessions_by_date_and_film:
sessions_by_date_and_film[session_date] = {} sessions_by_date_and_film[session_date] = {}
film_sessions_for_date = sessions_by_date_and_film[session_date] film_sessions_for_date = sessions_by_date_and_film[session_date]
if session.film not in film_sessions_for_date: if session.film not in film_sessions_for_date:
film_sessions_for_date[session.film] = [] film_sessions_for_date[session.film] = []
film_sessions_for_date[session.film].append(session) film_sessions_for_date[session.film].append(session)
for session_date, session_films in sessions_by_date_and_film.items(): for session_date, session_films in sessions_by_date_and_film.items():
@ -36,6 +41,7 @@ def film_details(request: HttpResponse, film_id: int) -> HttpResponse:
sessions_by_date_and_film[session_date][session_film].sort( sessions_by_date_and_film[session_date][session_film].sort(
key=lambda sorted_session: sorted_session.start_datetime, key=lambda sorted_session: sorted_session.start_datetime,
) )
context = { context = {
'film_sessions': sessions_by_date_and_film, 'film_sessions': sessions_by_date_and_film,
'item': item, 'item': item,
@ -45,4 +51,3 @@ def film_details(request: HttpResponse, film_id: int) -> HttpResponse:
'films/film_details.html', 'films/film_details.html',
context, context,
) )

View File

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -3,6 +3,7 @@ from datetime import date
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render from django.shortcuts import render
from films.models import Film from films.models import Film
from timetable.models import FilmSession from timetable.models import FilmSession
@ -16,9 +17,11 @@ def homepage(request):
session_date = session.start_datetime.date() session_date = session.start_datetime.date()
if session_date not in sessions_by_date_and_film: if session_date not in sessions_by_date_and_film:
sessions_by_date_and_film[session_date] = {} sessions_by_date_and_film[session_date] = {}
film_sessions_for_date = sessions_by_date_and_film[session_date] film_sessions_for_date = sessions_by_date_and_film[session_date]
if session.film not in film_sessions_for_date: if session.film not in film_sessions_for_date:
film_sessions_for_date[session.film] = [] film_sessions_for_date[session.film] = []
film_sessions_for_date[session.film].append(session) film_sessions_for_date[session.film].append(session)
for session_date, session_films in sessions_by_date_and_film.items(): for session_date, session_films in sessions_by_date_and_film.items():
@ -35,7 +38,7 @@ def homepage(request):
'films_sessions': sessions_by_date_and_film, 'films_sessions': sessions_by_date_and_film,
'today': date.today(), 'today': date.today(),
'tomorrow': date.today() + datetime.timedelta(days=1), 'tomorrow': date.today() + datetime.timedelta(days=1),
} },
) )
return HttpResponse( return HttpResponse(
template, template,

View File

@ -1,20 +1,19 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os import os
import sys import sys
def main(): def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CineSync.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CineSync.settings')
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:
raise ImportError( raise ImportError(
"Couldn't import Django. Are you sure it's installed and " "Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you " 'available on your PYTHONPATH environment variable? Did you '
"forget to activate a virtual environment?" 'forget to activate a virtual environment?',
) from exc ) from exc
execute_from_command_line(sys.argv) execute_from_command_line(sys.argv)

View File

@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from tickets.models import Ticket, Order from tickets.models import Order, Ticket
class TicketAdminInline(admin.StackedInline): class TicketAdminInline(admin.StackedInline):

View File

@ -6,7 +6,10 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("tickets", "0006_remove_ticket_profile_remove_ticket_session_and_more"), (
"tickets",
"0006_remove_ticket_profile_remove_ticket_session_and_more",
),
] ]
operations = [ operations = [

View File

@ -1,5 +1,12 @@
from django.db.models import ForeignKey, CASCADE, Model, IntegerField, DateTimeField, Manager
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db.models import (
CASCADE,
DateTimeField,
ForeignKey,
IntegerField,
Manager,
Model,
)
from timetable.models import FilmSession from timetable.models import FilmSession
from users.models import Profile from users.models import Profile
@ -7,8 +14,7 @@ from users.models import Profile
class TicketManager(Manager): class TicketManager(Manager):
def get_tickets_for_session(self, session_id): def get_tickets_for_session(self, session_id):
tickets = super().get_queryset().filter(order__session_id=session_id) return super().get_queryset().filter(order__session_id=session_id)
return tickets
class Order(Model): class Order(Model):

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,10 +1,10 @@
from django.urls import path from django.urls import path
from tickets.views import order_success, my_orders from tickets.views import my_orders, order_success
app_name = 'tickets' app_name = 'tickets'
urlpatterns = [ urlpatterns = [
path('order/success', order_success, name='order_success'), path('order/success', order_success, name='order_success'),
path('my/', my_orders, name='my_orders') path('my/', my_orders, name='my_orders'),
] ]

View File

@ -1,7 +1,7 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_list_or_404 from django.shortcuts import render
from tickets.models import Order, Ticket from tickets.models import Order
def order_success(request): def order_success(request):
@ -11,16 +11,11 @@ def order_success(request):
@login_required @login_required
def my_orders(request): def my_orders(request):
user = request.user user = request.user
orders = Order.objects.filter( queryset = Order.objects.filter(profile__id=user.profile.id)
profile__id=user.profile.id, queryset = queryset.select_related('session', 'session__film')
).select_related( queryset = queryset.prefetch_related('tickets')
'session', orders = queryset.order_by('-datetime_order')
'session__film',
).prefetch_related(
'tickets',
).order_by(
'-datetime_order'
)
context = { context = {
'my_orders': orders, 'my_orders': orders,
} }

View File

@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from timetable.models import Auditorium, Row, FilmSession from timetable.models import Auditorium, FilmSession, Row
class RowAdminInline(admin.StackedInline): class RowAdminInline(admin.StackedInline):

View File

@ -1,9 +1,8 @@
import pprint
from json import loads from json import loads
from django import forms from django import forms
from timetable.models import Auditorium, Row from timetable.models import Auditorium
class SeatSelectionForm(forms.Form): class SeatSelectionForm(forms.Form):
@ -17,13 +16,19 @@ class SeatSelectionForm(forms.Form):
for i, row in enumerate(auditorium.rows.all(), start=1): for i, row in enumerate(auditorium.rows.all(), start=1):
for seat in range(1, row.column_count + 1): for seat in range(1, row.column_count + 1):
choices.append((f'[{seat}, {str(i)}]', f'[{seat}, {str(i)}]')) choices.append((f'[{seat}, {str(i)}]', f'[{seat}, {str(i)}]'))
self.fields['selected_seats'].choices = choices self.fields['selected_seats'].choices = choices
for field in self.visible_fields(): for field in self.visible_fields():
field.field.widget.attrs.update({"class": "seat_checkbox"}) field.field.widget.attrs.update({'class': 'seat_checkbox'})
def clean_selected_seats(self): def clean_selected_seats(self):
selected_seats = self.cleaned_data['selected_seats'] return (
if isinstance(selected_seats, list) and all(isinstance(item, str) for item in selected_seats): [loads(field) for field in self.cleaned_data['selected_seats']]
selected_seats = [loads(field) for field in selected_seats] if isinstance(self.cleaned_data['selected_seats'], list)
return selected_seats and all(
isinstance(item, str)
for item in self.cleaned_data['selected_seats']
)
else self.cleaned_data['selected_seats']
)

View File

@ -26,12 +26,16 @@ class Migration(migrations.Migration):
), ),
( (
"number", "number",
models.CharField(max_length=20, verbose_name="Номер кинозала"), models.CharField(
max_length=20, verbose_name="Номер кинозала"
),
), ),
( (
"row_count", "row_count",
models.IntegerField( models.IntegerField(
validators=[django.core.validators.MinValueValidator(1)], validators=[
django.core.validators.MinValueValidator(1)
],
verbose_name="Количество рядов кресел в зале", verbose_name="Количество рядов кресел в зале",
), ),
), ),
@ -57,14 +61,18 @@ class Migration(migrations.Migration):
( (
"row_number", "row_number",
models.IntegerField( models.IntegerField(
validators=[django.core.validators.MinValueValidator(1)], validators=[
django.core.validators.MinValueValidator(1)
],
verbose_name="Номер ряда", verbose_name="Номер ряда",
), ),
), ),
( (
"column_count", "column_count",
models.IntegerField( models.IntegerField(
validators=[django.core.validators.MinValueValidator(1)], validators=[
django.core.validators.MinValueValidator(1)
],
verbose_name="Количество кресел в ряду", verbose_name="Количество кресел в ряду",
), ),
), ),

View File

@ -31,12 +31,16 @@ class Migration(migrations.Migration):
), ),
( (
"start_datetime", "start_datetime",
models.DateTimeField(verbose_name="Дата и время начала сеанса"), models.DateTimeField(
verbose_name="Дата и время начала сеанса"
),
), ),
( (
"price", "price",
models.FloatField( models.FloatField(
validators=[django.core.validators.MinValueValidator(1)], validators=[
django.core.validators.MinValueValidator(1)
],
verbose_name="Цена билета", verbose_name="Цена билета",
), ),
), ),

View File

@ -14,7 +14,9 @@ class Migration(migrations.Migration):
model_name="filmsession", model_name="filmsession",
name="end_datetime", name="end_datetime",
field=models.DateTimeField( field=models.DateTimeField(
blank=True, null=True, verbose_name="Дата и время начала сеанса" blank=True,
null=True,
verbose_name="Дата и время начала сеанса",
), ),
), ),
] ]

View File

@ -1,7 +1,16 @@
from datetime import timedelta from datetime import timedelta
from django.db.models import Model, CharField, IntegerField, CASCADE, DateTimeField, FloatField, ForeignKey, Manager
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db.models import (
CASCADE,
CharField,
DateTimeField,
FloatField,
ForeignKey,
IntegerField,
Manager,
Model,
)
from django.utils import timezone from django.utils import timezone
from films.models import Film from films.models import Film
@ -11,34 +20,23 @@ class FilmSessionsManager(Manager):
def nearest_timetable(self): def nearest_timetable(self):
current_datetime = timezone.now() current_datetime = timezone.now()
end_datetime = current_datetime + timedelta(days=5) end_datetime = current_datetime + timedelta(days=5)
films_sessions = super().get_queryset().select_related( queryset = super().get_queryset()
'film', queryset = queryset.select_related('film')
).prefetch_related( queryset = queryset.prefetch_related('film__genres', 'film__countries')
'film__genres', queryset = queryset.filter(
'film__countries',
).filter(
start_datetime__gte=current_datetime, start_datetime__gte=current_datetime,
start_datetime__lte=end_datetime, start_datetime__lte=end_datetime,
).order_by(
FilmSession.start_datetime.field.name,
) )
return films_sessions return queryset.order_by(FilmSession.start_datetime.field.name)
def all_timetable(self): def all_timetable(self):
current_datetime = timezone.now() current_datetime = timezone.now()
films_sessions = super().get_queryset().select_related( queryset = super().get_queryset()
'film', queryset = queryset.select_related('film')
).prefetch_related( queryset = queryset.prefetch_related('film__genres', 'film__countries')
'film__genres', queryset = queryset.filter(start_datetime__gte=current_datetime)
'film__countries', queryset = queryset.prefetch_related(FilmSession.film.field.name)
).filter( return queryset.order_by(FilmSession.start_datetime.field.name)
start_datetime__gte=current_datetime,
).prefetch_related(
FilmSession.film.field.name,
).order_by(
FilmSession.start_datetime.field.name,
)
return films_sessions
class Auditorium(Model): class Auditorium(Model):
@ -121,11 +119,17 @@ class FilmSession(Model):
) )
def __str__(self): def __str__(self):
return f'{self.film.name} - {str(self.start_datetime)} - {self.auditorium}' return (
f'{self.film.name} - {str(self.start_datetime)}'
f' - {self.auditorium}'
)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.start_datetime and self.film.duration: if self.start_datetime and self.film.duration:
self.end_datetime = self.start_datetime + timedelta(minutes=self.film.duration) self.end_datetime = self.start_datetime + timedelta(
minutes=self.film.duration,
)
super().save(*args, **kwargs) super().save(*args, **kwargs)
class Meta: class Meta:

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,6 +1,6 @@
from django.urls import path from django.urls import path
from timetable.views import timetable_view, session_view from timetable.views import session_view, timetable_view
app_name = 'time_table' app_name = 'time_table'

View File

@ -4,13 +4,13 @@ from datetime import date
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db import transaction from django.db import transaction
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from timetable.models import FilmSession, Row
from timetable.forms import SeatSelectionForm
from tickets.models import Order, Ticket from tickets.models import Order, Ticket
from timetable.forms import SeatSelectionForm
from timetable.models import FilmSession
def timetable_view(request): def timetable_view(request):
@ -21,9 +21,11 @@ def timetable_view(request):
session_date = session.start_datetime.date() session_date = session.start_datetime.date()
if session_date not in sessions_by_date_and_film: if session_date not in sessions_by_date_and_film:
sessions_by_date_and_film[session_date] = {} sessions_by_date_and_film[session_date] = {}
film_sessions_for_date = sessions_by_date_and_film[session_date] film_sessions_for_date = sessions_by_date_and_film[session_date]
if session.film not in film_sessions_for_date: if session.film not in film_sessions_for_date:
film_sessions_for_date[session.film] = [] film_sessions_for_date[session.film] = []
film_sessions_for_date[session.film].append(session) film_sessions_for_date[session.film].append(session)
for session_date, session_films in sessions_by_date_and_film.items(): for session_date, session_films in sessions_by_date_and_film.items():
@ -31,6 +33,7 @@ def timetable_view(request):
sessions_by_date_and_film[session_date][session_film].sort( sessions_by_date_and_film[session_date][session_film].sort(
key=lambda sorted_session: sorted_session.start_datetime, key=lambda sorted_session: sorted_session.start_datetime,
) )
template = render( template = render(
request, request,
'timetable/timetable.html', 'timetable/timetable.html',
@ -38,7 +41,7 @@ def timetable_view(request):
'films_sessions': sessions_by_date_and_film, 'films_sessions': sessions_by_date_and_film,
'today': date.today(), 'today': date.today(),
'tomorrow': date.today() + datetime.timedelta(days=1), 'tomorrow': date.today() + datetime.timedelta(days=1),
} },
) )
return HttpResponse( return HttpResponse(
template, template,
@ -60,7 +63,10 @@ def session_view(request, sess_id):
height = round(session.auditorium.rows.count() * 4 + 7) height = round(session.auditorium.rows.count() * 4 + 7)
tickets = Ticket.objects.get_tickets_for_session(session.pk) tickets = Ticket.objects.get_tickets_for_session(session.pk)
occupied_seats = [f"{str(ticket.row_number)}-{str(ticket.column_number)}" for ticket in tickets] occupied_seats = [
f'{str(ticket.row_number)}-{str(ticket.column_number)}'
for ticket in tickets
]
if request.method == 'POST': if request.method == 'POST':
form = SeatSelectionForm(request.POST, auditorium=session.auditorium) form = SeatSelectionForm(request.POST, auditorium=session.auditorium)

View File

@ -1,6 +1,5 @@
from django import forms from django import forms
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.forms import DateInput, ModelForm
from django.contrib.auth.forms import ( from django.contrib.auth.forms import (
AuthenticationForm, AuthenticationForm,
PasswordChangeForm, PasswordChangeForm,
@ -8,6 +7,7 @@ from django.contrib.auth.forms import (
UserChangeForm, UserChangeForm,
UserCreationForm, UserCreationForm,
) )
from django.forms import DateInput, ModelForm
from users.models import Profile from users.models import Profile

View File

@ -30,12 +30,16 @@ class Migration(migrations.Migration):
( (
"birthday", "birthday",
models.DateField( models.DateField(
blank=True, null=True, verbose_name="Дата рождения пользователя" blank=True,
null=True,
verbose_name="Дата рождения пользователя",
), ),
), ),
( (
"role", "role",
models.CharField(max_length=20, verbose_name="Роль пользователя"), models.CharField(
max_length=20, verbose_name="Роль пользователя"
),
), ),
( (
"image", "image",

View File

@ -19,7 +19,9 @@ class Migration(migrations.Migration):
model_name="profile", model_name="profile",
name="genres", name="genres",
field=models.ManyToManyField( field=models.ManyToManyField(
related_name="profiles", related_query_name="profiles", to="films.genre" related_name="profiles",
related_query_name="profiles",
to="films.genre",
), ),
), ),
] ]

View File

@ -1,7 +1,15 @@
import time import time
from django.conf import settings from django.conf import settings
from django.db.models import Model, OneToOneField, CASCADE, DateField, CharField, ImageField, ManyToManyField from django.db.models import (
CASCADE,
CharField,
DateField,
ImageField,
ManyToManyField,
Model,
OneToOneField,
)
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from sorl.thumbnail import get_thumbnail from sorl.thumbnail import get_thumbnail

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -6,7 +6,6 @@ from django.urls import reverse_lazy
from users.forms import ( from users.forms import (
CustomAuthenticationForm, CustomAuthenticationForm,
CustomPasswordChangeForm, CustomPasswordChangeForm,
CustomSetPasswordForm,
) )
from users.views import profile, signup from users.views import profile, signup

View File

@ -1,12 +1,9 @@
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.core.mail import send_mail
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import View
from users.forms import SignUpForm, ProfileForm, UserForm from users.forms import ProfileForm, SignUpForm, UserForm
from users.models import Profile from users.models import Profile
__all__ = [] __all__ = []
@ -59,4 +56,3 @@ def profile(request):
'user': request.user, 'user': request.user,
}, },
) )

View File

@ -1,5 +1,6 @@
[tool.black] [tool.black]
line-length = 79 line-length = 79
skip-string-normalization = 'true'
exclude = ''' exclude = '''
venv/ venv/
.git/ .git/