начал делать главную страницу, сделал админку для фильмов и жанров, поправил хеадер
This commit is contained in:
parent
50d00cecba
commit
409d81b82f
@ -1,24 +1,22 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
|
||||
from users.models import Profile
|
||||
|
||||
user = get_user_model()
|
||||
admin.site.unregister(user)
|
||||
from films.models import Film, Genre
|
||||
|
||||
|
||||
class ProfileInline(admin.TabularInline):
|
||||
can_delete = False
|
||||
model = Profile
|
||||
fields = [
|
||||
Profile.birthday.field.name,
|
||||
Profile.image.field.name,
|
||||
@admin.register(Film)
|
||||
class ItemAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
Film.name.field.name,
|
||||
Film.duration.field.name,
|
||||
]
|
||||
|
||||
filter_horizontal = [
|
||||
Film.genres.field.name,
|
||||
]
|
||||
|
||||
|
||||
@admin.register(user)
|
||||
class UserAdmin(UserAdmin):
|
||||
inlines = [
|
||||
ProfileInline,
|
||||
@admin.register(Genre)
|
||||
class GenreAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
Genre.name.field.name,
|
||||
]
|
||||
|
||||
24
CineSync/films/migrations/0004_film_image.py
Normal file
24
CineSync/films/migrations/0004_film_image.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.2 on 2024-04-17 13:08
|
||||
|
||||
from django.db import migrations, models
|
||||
import films.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("films", "0003_film_description"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="film",
|
||||
name="image",
|
||||
field=models.ImageField(
|
||||
blank=True,
|
||||
null=True,
|
||||
upload_to=films.models.Film.get_upload_path,
|
||||
verbose_name="Изображение фильма",
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -1,4 +1,6 @@
|
||||
import time
|
||||
from datetime import timedelta
|
||||
from random import shuffle
|
||||
|
||||
from django.db.models import (
|
||||
Model,
|
||||
@ -18,6 +20,16 @@ class FilmManager(Manager):
|
||||
release_date__lt=timezone.now(),
|
||||
)
|
||||
|
||||
def on_main(self):
|
||||
current_datetime = timezone.now()
|
||||
end_datetime = current_datetime + timedelta(days=5)
|
||||
films_with_sessions = Film.objects.filter(
|
||||
sessions__start_datetime__gte=current_datetime,
|
||||
sessions__start_datetime__lte=end_datetime,
|
||||
).exclude(image=None).distinct()
|
||||
shuffle(list(films_with_sessions))
|
||||
return films_with_sessions
|
||||
|
||||
|
||||
class Genre(Model):
|
||||
name = CharField(
|
||||
@ -35,7 +47,7 @@ class Genre(Model):
|
||||
|
||||
class Film(Model):
|
||||
def get_upload_path(self, filename):
|
||||
return f'users/avatars/{self.pk}/{time.time()}_{filename}'
|
||||
return f'users/films/{self.pk}/{time.time()}_{filename}'
|
||||
|
||||
objects = FilmManager()
|
||||
|
||||
@ -67,7 +79,7 @@ class Film(Model):
|
||||
image = ImageField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name='Аватар пользователя',
|
||||
verbose_name='Изображение фильма',
|
||||
upload_to=get_upload_path,
|
||||
)
|
||||
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
||||
from films.models import Film
|
||||
|
||||
|
||||
def homepage(request):
|
||||
films = Film.objects.on_main()
|
||||
template = render(
|
||||
request,
|
||||
'home/homepage.html'
|
||||
'home/homepage.html',
|
||||
context={
|
||||
'films_preview': films
|
||||
}
|
||||
)
|
||||
return HttpResponse(
|
||||
template,
|
||||
|
||||
24
CineSync/static/css/home/homepage.css
Normal file
24
CineSync/static/css/home/homepage.css
Normal file
@ -0,0 +1,24 @@
|
||||
.carousel_films {
|
||||
margin-top: 5vw;
|
||||
height: 30vw;
|
||||
width: 100%;
|
||||
}
|
||||
.film_card_image {
|
||||
object-fit: cover;
|
||||
height: 30vw !important;
|
||||
width: 70% !important;
|
||||
border-radius: 3vw;
|
||||
}
|
||||
.carousel-item-next, .carousel-item-prev, .carousel-item.active {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.caption_block {
|
||||
background-color: rgba(13, 39, 58, 0.8);
|
||||
border-radius: 2vw;
|
||||
width: 40%;
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-left: 15%;
|
||||
}
|
||||
@ -4,5 +4,36 @@
|
||||
Главная
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
|
||||
<link href="{% static 'css/home/homepage.css' %}" rel="stylesheet">
|
||||
<div class="carousel_films">
|
||||
<div id="carouselWhite" class="carousel carousel slide">
|
||||
{{films}}
|
||||
<div class="carousel-indicators">
|
||||
{% for film in films_preview %}
|
||||
<button type="button" data-bs-target="#carouselWhite" data-bs-slide-to="{{ forloop.counter0 }}"
|
||||
class="active"
|
||||
aria-current="true" aria-label="{{film.name|truncatewords_html:5}}"></button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="carousel-inner">
|
||||
{% for film in films_preview %}
|
||||
<div class="carousel-item {% if forloop.counter0 == 0 %} active {% endif %}" data-bs-interval="10000">
|
||||
<img src="{{ film.image.url }}" class="d-block w-100 film_card_image" alt="Фотография фильма не найдена">
|
||||
<div class="carousel-caption d-none d-md-block caption_block">
|
||||
<h5>{{ film.name }}</h5>
|
||||
<p>{{ film.description|truncatewords_html:10|safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button class="carousel-control-prev" type="button" data-bs-target="#carouselWhite" data-bs-slide="prev">
|
||||
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">Previous</span>
|
||||
</button>
|
||||
<button class="carousel-control-next" type="button" data-bs-target="#carouselWhite" data-bs-slide="next">
|
||||
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">Next</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -30,6 +30,9 @@
|
||||
<img src="{% static 'img/user.png' %}" class="header_icon col-4">
|
||||
{% endif %}
|
||||
</a>
|
||||
{% if user.is_staff %}
|
||||
<a class="btn btn-primary" href="/admin">Админка</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2 on 2024-04-17 14:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("timetable", "0004_alter_row_auditorium"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="filmsession",
|
||||
name="end_datetime",
|
||||
field=models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="Дата и время начала сеанса"
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -1,5 +1,6 @@
|
||||
from django.db.models import Model, CharField, IntegerField, OneToOneField, CASCADE, DateTimeField, FloatField, \
|
||||
ForeignKey
|
||||
from datetime import timedelta
|
||||
|
||||
from django.db.models import Model, CharField, IntegerField, CASCADE, DateTimeField, FloatField, ForeignKey
|
||||
from django.core.validators import MinValueValidator
|
||||
|
||||
from films.models import Film
|
||||
@ -58,6 +59,13 @@ class FilmSession(Model):
|
||||
verbose_name='Дата и время начала сеанса',
|
||||
)
|
||||
|
||||
end_datetime = DateTimeField(
|
||||
verbose_name='Дата и время начала сеанса',
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
|
||||
price = FloatField(
|
||||
verbose_name='Цена билета',
|
||||
validators=[
|
||||
@ -72,7 +80,6 @@ class FilmSession(Model):
|
||||
related_name='sessions',
|
||||
related_query_name='sessions',
|
||||
)
|
||||
|
||||
auditorium = ForeignKey(
|
||||
Auditorium,
|
||||
on_delete=CASCADE,
|
||||
@ -81,6 +88,11 @@ class FilmSession(Model):
|
||||
related_query_name='sessions',
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.start_datetime and self.film.duration:
|
||||
self.end_datetime = self.start_datetime + timedelta(minutes=self.film.duration)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
db_table = 'timetable_film_sessions'
|
||||
verbose_name = 'Сеанс'
|
||||
|
||||
@ -1,3 +1,24 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
|
||||
# Register your models here.
|
||||
from users.models import Profile
|
||||
|
||||
user = get_user_model()
|
||||
admin.site.unregister(user)
|
||||
|
||||
|
||||
class ProfileInline(admin.TabularInline):
|
||||
can_delete = False
|
||||
model = Profile
|
||||
fields = [
|
||||
Profile.birthday.field.name,
|
||||
Profile.image.field.name,
|
||||
]
|
||||
|
||||
|
||||
@admin.register(user)
|
||||
class UserAdmin(UserAdmin):
|
||||
inlines = [
|
||||
ProfileInline,
|
||||
]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user