Skip to content
Snippets Groups Projects
Verified Commit 90e71e84 authored by Tom Teichler's avatar Tom Teichler :beers:
Browse files

Merge branch 'master' into core#65

parents 6058cb04 d0658f59
No related branches found
No related tags found
1 merge request!10Make page titles and headers consistent. Advances BiscuIT-ng#65.
......@@ -6,7 +6,7 @@ MENUS = {
'name': _('Timetables'),
'url': '#',
'root': True,
'validators': ['menu_generator.validators.is_authenticated'],
'validators': ['menu_generator.validators.is_authenticated', 'biscuit.core.util.core_helpers.has_person'],
'submenu': [
{
'name': _('Timetable'),
......
# Generated by Django 2.2.4 on 2019-09-03 14:10
import biscuit.apps.chronos.util
import biscuit.core.util.core_helpers
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('chronos', '0004_auto_20190821_1550'),
]
operations = [
migrations.AddField(
model_name='lesson',
name='school',
field=models.ForeignKey(default=biscuit.core.util.core_helpers.get_current_school, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
),
migrations.AddField(
model_name='lessonperiod',
name='school',
field=models.ForeignKey(default=biscuit.core.util.core_helpers.get_current_school, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
),
migrations.AddField(
model_name='lessonsubstitution',
name='school',
field=models.ForeignKey(default=biscuit.core.util.core_helpers.get_current_school, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
),
migrations.AddField(
model_name='room',
name='school',
field=models.ForeignKey(default=biscuit.core.util.core_helpers.get_current_school, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
),
migrations.AddField(
model_name='subject',
name='school',
field=models.ForeignKey(default=biscuit.core.util.core_helpers.get_current_school, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
),
migrations.AddField(
model_name='timeperiod',
name='school',
field=models.ForeignKey(default=biscuit.core.util.core_helpers.get_current_school, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
),
migrations.AlterField(
model_name='room',
name='name',
field=models.CharField(max_length=30, verbose_name='Long name'),
),
migrations.AlterField(
model_name='room',
name='short_name',
field=models.CharField(max_length=10, verbose_name='Short name, e.g. room number'),
),
migrations.AlterField(
model_name='subject',
name='abbrev',
field=models.CharField(max_length=10, verbose_name='Abbreviation of subject in timetable'),
),
migrations.AlterField(
model_name='subject',
name='name',
field=models.CharField(max_length=30, verbose_name='Long name of subject'),
),
migrations.AlterUniqueTogether(
name='room',
unique_together={('school', 'name'), ('school', 'short_name')},
),
migrations.AlterUniqueTogether(
name='subject',
unique_together={('school', 'abbrev'), ('school', 'name')},
),
migrations.AlterUniqueTogether(
name='timeperiod',
unique_together={('school', 'weekday', 'period')},
),
]
......@@ -5,10 +5,12 @@ from django.core import validators
from django.db import models
from django.utils.translation import ugettext_lazy as _
from biscuit.core.mixins import SchoolRelated
from .util import current_week
class TimePeriod(models.Model):
class TimePeriod(SchoolRelated):
WEEKDAY_CHOICES = [
(0, _('Sunday')),
(1, _('Monday')),
......@@ -39,15 +41,15 @@ class TimePeriod(models.Model):
return periods
class Meta:
unique_together = [['weekday', 'period']]
unique_together = [['school', 'weekday', 'period']]
ordering = ['weekday', 'period']
class Subject(models.Model):
class Subject(SchoolRelated):
abbrev = models.CharField(verbose_name=_(
'Abbreviation of subject in timetable'), max_length=10, unique=True)
'Abbreviation of subject in timetable'), max_length=10)
name = models.CharField(verbose_name=_(
'Long name of subject'), max_length=30, unique=True)
'Long name of subject'), max_length=30)
colour_fg = models.CharField(verbose_name=_('Foreground colour in timetable'), blank=True, validators=[
validators.RegexValidator(r'#[0-9A-F]{6}')], max_length=7)
......@@ -59,22 +61,24 @@ class Subject(models.Model):
class Meta:
ordering = ['name', 'abbrev']
unique_together = [['school', 'abbrev'], ['school', 'name']]
class Room(models.Model):
class Room(SchoolRelated):
short_name = models.CharField(verbose_name=_(
'Short name, e.g. room number'), max_length=10, unique=True)
'Short name, e.g. room number'), max_length=10)
name = models.CharField(verbose_name=_('Long name'),
max_length=30, unique=True)
max_length=30)
def __str__(self) -> str:
return '%s (%s)' % (self.name, self.short_name)
class Meta:
ordering = ['name', 'short_name']
unique_together = [['school', 'short_name'], ['school', 'name']]
class Lesson(models.Model):
class Lesson(SchoolRelated):
subject = models.ForeignKey(
'Subject', on_delete=models.CASCADE, related_name='lessons')
teachers = models.ManyToManyField('core.Person', related_name='lessons')
......@@ -99,7 +103,7 @@ class Lesson(models.Model):
ordering = ['date_start']
class LessonSubstitution(models.Model):
class LessonSubstitution(SchoolRelated):
week = models.IntegerField(verbose_name=_('Week'),
default=current_week)
......@@ -118,14 +122,14 @@ class LessonSubstitution(models.Model):
'lesson_period__period__weekday', 'lesson_period__period__period']
class LessonPeriod(models.Model):
class LessonPeriod(SchoolRelated):
lesson = models.ForeignKey('Lesson', models.CASCADE, related_name='lesson_periods')
period = models.ForeignKey('TimePeriod', models.CASCADE, related_name='lesson_periods')
room = models.ForeignKey('Room', models.CASCADE, null=True, related_name='lesson_periods')
def get_substitution(self, week: Optional[int] = None) -> LessonSubstitution:
wanted_week = week or current_week()
wanted_week = week or getattr(self, '_week', None) or current_week()
return self.substitutions.filter(week=wanted_week).first()
def get_subject(self) -> Optional[Subject]:
......
......@@ -11,8 +11,21 @@
{% block page_title %}{% blocktrans %}Timetable{% endblocktrans %}{% endblock %}
{% block content %}
<div class="d-flex justify-content-between">
<div>
<h1>{{ day }}</h1>
</div>
<div class="btn-group" role="group" aria-label="Day actions">
<a href="{% url 'timetable_by_week' week_prev %}" class="btn btn-secondary">
{% fa 'arrow-left' %}
</a>
<a href="{% url 'timetable_by_week' week_next %}" class="btn btn-secondary">
{% fa 'arrow-right' %}
</a>
</div>
</div>
<form method="get">
{% csrf_token %}
<ul id="timetable_select_form">
{{ select_form.as_ul }}
</ul>
......
......@@ -5,6 +5,7 @@ from . import views
urlpatterns = [
path('timetable', views.timetable, name='timetable'),
path('timetable/<int:week>', views.timetable, name='timetable_by_week'),
path('lessons', views.lessons_day, name='lessons_day'),
path('lessons/<when>', views.lessons_day, name='lessons_day_by_date'),
path('lessons/<int:id_>/<int:week>/substition', views.edit_substitution, name='edit_substitution')
......
from collections import OrderedDict
from datetime import date, datetime, timedelta
from collections import OrderedDict
from typing import Optional
from django.contrib.auth.decorators import login_required
from django.db.models import Max, Min
from django.db.models import Max, Min, Q
from django.http import HttpRequest, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.views.decorators.cache import cache_page
from django.urls import reverse
from django.utils.translation import ugettext as _
from django_tables2 import RequestConfig
from biscuit.core.decorators import admin_required
......@@ -20,16 +22,22 @@ from .tables import LessonsTable
@login_required
def timetable(request: HttpRequest) -> HttpResponse:
@cache_page(60 * 60 * 12)
def timetable(request: HttpRequest, week: Optional[int] = None) -> HttpResponse:
context = {}
lesson_periods = LessonPeriod.objects.all()
wanted_week = week or current_week()
lesson_periods = LessonPeriod.objects.filter(
lesson__date_start__gte=week_days(wanted_week)[0],
lesson__date_end__lte=week_days(wanted_week)[-1]
).extra(select={'_week': wanted_week})
if request.GET.get('group', None) or request.GET.get('teacher', None) or request.GET.get('room', None):
# Incrementally filter lesson periods by GET parameters
if 'group' in request.GET and request.GET['group']:
lesson_periods = lesson_periods.filter(
lesson__groups__pk=int(request.GET['group']))
Q(lesson__groups__pk=int(request.GET['group'])) | Q(lesson__groups__parent_groups__pk=int(request.GET['group'])))
if 'teacher' in request.GET and request.GET['teacher']:
lesson_periods = lesson_periods.filter(
lesson__teachers__pk=int(request.GET['teacher']))
......@@ -78,7 +86,9 @@ def timetable(request: HttpRequest) -> HttpResponse:
context['lesson_periods'] = OrderedDict(sorted(per_day.items()))
context['periods'] = TimePeriod.get_times_dict()
context['weekdays'] = dict(TimePeriod.WEEKDAY_CHOICES)
context['current_week'] = current_week()
context['week'] = wanted_week
context['week_prev'] = wanted_week - 1
context['week_next'] = wanted_week + 1
context['select_form'] = select_form
return render(request, 'chronos/tt_week.html', context)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment