Add school schedules page & logic

remotes/origin/hasaccess
Ivlev Denis 8 years ago
parent a8d0532e63
commit 8f8b20682a
  1. 2
      apps/school/fixtures/school_schedules.json
  2. 17
      apps/school/migrations/0012_auto_20180417_1344.py
  3. 63
      apps/school/models.py
  4. 36
      apps/school/templates/blocks/schedule.html
  5. 28
      apps/school/views.py
  6. 17
      project/templates/blocks/header.html
  7. 11
      project/views.py

@ -34,7 +34,7 @@
"pk": 3,
"fields": {
"weekday": 3,
"title": "Пластелин",
"title": "Пластилин",
"short_description": "Однажды он затеял скандал на торговой площади ради леденца",
"description": "Однажды он затеял скандал на торговой площади ради леденца, вокруг собралась толпа, и полицейские попросили хозяина лавки открыть её во время сиесты и подарить мальчику сладость.",
"materials": "Он добивался своего капризами и симуляцией, всегда стремился выделиться и привлечь к себе внимание.",

@ -0,0 +1,17 @@
# Generated by Django 2.0.3 on 2018-04-17 10:44
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('school', '0011_schoolschedule_short_description'),
]
operations = [
migrations.AlterModelOptions(
name='schoolscheduleimage',
options={'ordering': ('-created_at',), 'verbose_name': 'Изображение работ', 'verbose_name_plural': 'Изображения работ'},
),
]

@ -1,9 +1,10 @@
from django.db import models
from django.utils.timezone import now
from project.mixins import BaseModel, DeactivatedMixin
from apps.content.models import ImageObject
from apps.course.models import Comment
from apps.payment import models as payment_models
class SchoolSchedule(models.Model):
@ -16,14 +17,20 @@ class SchoolSchedule(models.Model):
(6, 'суббота'),
(7, 'воскресенье'),
)
weekday = models.PositiveSmallIntegerField('День недели', choices=WEEKDAY_CHOICES, unique=True)
weekday = models.PositiveSmallIntegerField(
'День недели', choices=WEEKDAY_CHOICES, unique=True
)
title = models.CharField('Заголовок', default='', max_length=100, db_index=True)
short_description = models.CharField('Короткое описание', default='', max_length=100, db_index=True)
short_description = models.CharField(
'Короткое описание', default='', max_length=100, db_index=True
)
description = models.TextField('Описание')
materials = models.TextField('Материалы')
age = models.PositiveSmallIntegerField('Возраст', default=0)
month_price = models.DecimalField('Цена', max_digits=8, decimal_places=2, default=0)
day_discount = models.DecimalField('Скидка, в валюте', max_digits=8, decimal_places=2, default=0)
day_discount = models.DecimalField(
'Скидка, в валюте', max_digits=8, decimal_places=2, default=0
)
start_at = models.TimeField('Начало урока', null=True)
class Meta:
@ -34,16 +41,45 @@ class SchoolSchedule(models.Model):
def __str__(self):
return dict(self.WEEKDAY_CHOICES).get(self.weekday, '')
def is_online(self):
return now().isoweekday() == self.weekday and now().time() >= self.start_at
def is_purchased(self):
try:
school_payment = payment_models.SchoolPayment.objects.get(
weekdays__contains=[self.weekday],
date_start__gte=now().date(),
date_end__lte=now().date(),
)
except payment_models.SchoolPayment.DoesNotExist:
return False
else:
return school_payment.is_deliverable()
def current_live_lesson(self):
now_time = now()
weekday = self.weekday
live_lesson = LiveLesson.objects.filter(
date__week_day=weekday + 1 if weekday % 7 else 1,
date__gte=now_time.date(),
).first()
return live_lesson
class SchoolScheduleImage(models.Model):
schoolschedule = models.ForeignKey(
SchoolSchedule, on_delete=models.CASCADE,
verbose_name='День занятия', related_name='schoolschedule_images'
SchoolSchedule,
on_delete=models.CASCADE,
verbose_name='День занятия',
related_name='schoolschedule_images',
)
img = models.ForeignKey(
ImageObject, related_name='schoolschedule_images',
verbose_name='Объект изображения', on_delete=models.CASCADE,
null=True, blank=True,
ImageObject,
related_name='schoolschedule_images',
verbose_name='Объект изображения',
on_delete=models.CASCADE,
null=True,
blank=True,
)
created_at = models.DateTimeField(auto_now_add=True)
@ -61,9 +97,12 @@ class LiveLesson(BaseModel, DeactivatedMixin):
stream = models.URLField('Ссылка на VIMEO', default='', blank=True)
date = models.DateField(null=True, blank=True)
cover = models.ForeignKey(
ImageObject, related_name='livelesson_covers',
verbose_name='Обложка урока школы', on_delete=models.CASCADE,
null=True, blank=True,
ImageObject,
related_name='livelesson_covers',
verbose_name='Обложка урока школы',
on_delete=models.CASCADE,
null=True,
blank=True,
)
created_at = models.DateTimeField(auto_now_add=True)

@ -1,31 +1,44 @@
{% load static %}
{% load thumbnail %}
<div class="section">
<div class="section__center center center_md">
<div class="title title_center">Расписание</div>
<div class="timing js-timing">
<div class="timing__week">
{% for school_schedule in school_schedules %}
{% with current_live_lesson=school_schedule.current_live_lesson %}
<div class="timing__item js-timing-item">
<div class="timing__cell">
<div class="timing__info">
<div class="timing__day active">{{ school_schedule }}</div>
<div class="timing__date">2 апреля</div>
<div class="timing__day{% if school_schedule.is_online %} active{% endif %}">
{{ school_schedule }}
</div>
{% if current_live_lesson %}
<div class="timing__date">{{ current_live_lesson.date }}</div>
{% endif %}
</div>
<div class="timing__buy">
<div class="timing__time">17:00 (МСК)</div>
<a class="timing__btn btn" href="#">купить</a>
<div class="timing__time">{{ school_schedule.start_at }} (МСК)</div>
{% include './pay_btn.html' %}
</div>
</div>
<div class="timing__cell">
<div class="timing__preview">
<img class="timing__pic" src="{% static 'img/user.jpg' %}">
{% thumbnail current_live_lesson.cover.image "70x70" crop="center" as im %}
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"/>
{% empty %}
<img class="timing__pic" src="{% static 'img/no_cover.png' %}" width="70px" height="70px"/>
{% endthumbnail %}
</div>
</div>
<div class="timing__cell">
<div class="timing__title">{{ school_schedule.title }},
<span class="bold">Санкт-Петербург</span>
<div class="timing__title">{{ school_schedule.title }}{% if current_live_lesson %},
<span class="bold">{{ current_live_lesson.title }}</span>
{% endif %}
</div>
<div class="timing__content">{{ school_schedule.short_description }}</div>
{% if current_live_lesson %}
<div class="timing__content">{{ current_live_lesson.short_description }}</div>
{% endif %}
<div class="timing__more">
<div class="timing__head">Материалы</div>
<div class="timing__row">
@ -45,7 +58,9 @@
<div class="timing__works">
{% for image in school_schedule.schoolschedule_images.all %}
<a class="timing__work" href="#">
<img class="timing__pic" src="{{ image.img.image.url }}">
{% thumbnail image.img.image "48x48" crop="center" as im %}
<img class="timing__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"/>
{% endthumbnail %}
</a>
{% endfor %}
</div>
@ -60,6 +75,7 @@
</button>
</div>
</div>
{% endwith %}
{% endfor %}
{% comment %}
<div class="timing__item js-timing-item">
@ -516,7 +532,7 @@
{% endcomment %}
</div>
<div class="timing__foot">
<a class="timing__btn btn" href="#">купить</a>
{% include './pay_btn.html' %}
<a class="timing__print" href="#">Распечатать расписание
<span class="bold">чтобы не забыть</span>
<svg class="icon icon-print">

@ -1,10 +1,13 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required, user_passes_test
from django.db.models import Min
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.utils.timezone import now
from django.views.generic import ListView, UpdateView, TemplateView, DetailView
from apps.payment.models import SchoolPayment
from .models import LiveLesson, SchoolSchedule
User = get_user_model()
@ -12,11 +15,11 @@ User = get_user_model()
def is_admin_or_teacher(function=None, login_url=None):
actual_decorator = user_passes_test(
lambda u: u.role in [User.ADMIN_ROLE, User.TEACHER_ROLE],
login_url=login_url,
lambda u: u.role in [User.ADMIN_ROLE, User.TEACHER_ROLE], login_url=login_url
)
if function:
return actual_decorator(function)
return actual_decorator
@ -26,11 +29,28 @@ class LiveLessonsView(ListView):
template_name = 'school/livelessons_list.html'
@method_decorator([login_required, is_admin_or_teacher], name='dispatch')
@method_decorator(login_required, name='dispatch')
class LiveLessonsDetailView(DetailView):
model = LiveLesson
template_name = 'school/livelesson_detail.html'
def get(self, request, pk=None):
response = super().get(request, pk=pk)
try:
school_payment = SchoolPayment.objects.get(
user=request.user, date_start__gte=now(), date__end__lte=now()
)
except SchoolPayment.DoesNotExist:
school_payment = None
if request.user.role not in [User.ADMIN_ROLE, User.TEACHER_ROLE] or not (
request.user.role == User.USER_ROLE and
school_payment and
school_payment.is_deliverable()
):
raise Http404
return response
@method_decorator([login_required, is_admin_or_teacher], name='dispatch')
class LiveLessonEditView(TemplateView):
@ -57,6 +77,6 @@ class SchoolView(TemplateView):
context = super().get_context_data()
context.update({
'school_schedules': SchoolSchedule.objects.all(),
'min_school_price': SchoolSchedule.objects.all().aggregate(Min('month_price'))['month_price__min'],
'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'],
})
return context

@ -1,4 +1,4 @@
{% load static %} {% load active_link_tags %} {% load category_menu_items from lilcity_category %}
{% load static %} {% load thumbnail %} {% load active_link_tags %} {% load category_menu_items from lilcity_category %}
<header class="header header_bg js-header">
<div class="header__center center">
<div class="header__container">
@ -27,8 +27,9 @@
<nav class="header__nav">
<div class="header__group">
<a class="header__section header__section_sub js-header-section {% active_link 'school:school' %}" href="{% url 'school:school' %}">
ОНЛАЙН-ШКОЛА
ОНЛАЙН-ШКОЛА {% if online %}
<div class="header__dot"></div>
{% endif %}
</a>
<div class="header__list js-header-list">
<a class="header__link" data-scroll href="/#about">
@ -81,15 +82,13 @@
</div>
{% if request.user.is_authenticated %}
<div class="header__login">
{% if request.user.photo %}
<div class="header__ava ava">
<img class="ava__pic" src="{{ request.user.photo.url }}">
{% thumbnail request.user.photo "48x48" crop="center" as im %}
<img class="ava__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
{% empty %}
<img class="ava__pic" src="{% static 'img/no_cover.png' %}" width="48px" height="48px" />
{% endthumbnail %}
</div>
{% else %}
<div class="header__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
{% endif %}
<div class="header__drop">
{% if request.user.role >= request.user.AUTHOR_ROLE %}
<a class="header__link header__link_border" href="{% url 'user-edit-payments' request.user.id %}">{{ request.user.balance }} руб.</a>

@ -1,6 +1,7 @@
from django.db.models import Min
from django.contrib.auth import get_user_model
from django.views.generic import TemplateView
from django.utils.timezone import now
from apps.course.models import Course
from apps.school.models import SchoolSchedule
@ -13,7 +14,17 @@ class IndexView(TemplateView):
def get_context_data(self):
context = super().get_context_data()
now_time = now()
try:
school_schedule = SchoolSchedule.objects.get(weekday=now_time.isoweekday())
except SchoolSchedule.DoesNotExist:
online = False
else:
online = school_schedule.start_at <= now().time()
context.update({
'online': online,
'course_items': Course.objects.filter(status=Course.PUBLISHED)[:6],
'school_schedules': SchoolSchedule.objects.all(),
'min_school_price': SchoolSchedule.objects.all().aggregate(Min('month_price'))['month_price__min'],

Loading…
Cancel
Save