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 = { ...@@ -6,7 +6,7 @@ MENUS = {
'name': _('Timetables'), 'name': _('Timetables'),
'url': '#', 'url': '#',
'root': True, 'root': True,
'validators': ['menu_generator.validators.is_authenticated'], 'validators': ['menu_generator.validators.is_authenticated', 'biscuit.core.util.core_helpers.has_person'],
'submenu': [ 'submenu': [
{ {
'name': _('Timetable'), '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 ...@@ -5,10 +5,12 @@ from django.core import validators
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from biscuit.core.mixins import SchoolRelated
from .util import current_week from .util import current_week
class TimePeriod(models.Model): class TimePeriod(SchoolRelated):
WEEKDAY_CHOICES = [ WEEKDAY_CHOICES = [
(0, _('Sunday')), (0, _('Sunday')),
(1, _('Monday')), (1, _('Monday')),
...@@ -39,15 +41,15 @@ class TimePeriod(models.Model): ...@@ -39,15 +41,15 @@ class TimePeriod(models.Model):
return periods return periods
class Meta: class Meta:
unique_together = [['weekday', 'period']] unique_together = [['school', 'weekday', 'period']]
ordering = ['weekday', 'period'] ordering = ['weekday', 'period']
class Subject(models.Model): class Subject(SchoolRelated):
abbrev = models.CharField(verbose_name=_( 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=_( 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=[ colour_fg = models.CharField(verbose_name=_('Foreground colour in timetable'), blank=True, validators=[
validators.RegexValidator(r'#[0-9A-F]{6}')], max_length=7) validators.RegexValidator(r'#[0-9A-F]{6}')], max_length=7)
...@@ -59,22 +61,24 @@ class Subject(models.Model): ...@@ -59,22 +61,24 @@ class Subject(models.Model):
class Meta: class Meta:
ordering = ['name', 'abbrev'] ordering = ['name', 'abbrev']
unique_together = [['school', 'abbrev'], ['school', 'name']]
class Room(models.Model): class Room(SchoolRelated):
short_name = models.CharField(verbose_name=_( 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'), name = models.CharField(verbose_name=_('Long name'),
max_length=30, unique=True) max_length=30)
def __str__(self) -> str: def __str__(self) -> str:
return '%s (%s)' % (self.name, self.short_name) return '%s (%s)' % (self.name, self.short_name)
class Meta: class Meta:
ordering = ['name', 'short_name'] ordering = ['name', 'short_name']
unique_together = [['school', 'short_name'], ['school', 'name']]
class Lesson(models.Model): class Lesson(SchoolRelated):
subject = models.ForeignKey( subject = models.ForeignKey(
'Subject', on_delete=models.CASCADE, related_name='lessons') 'Subject', on_delete=models.CASCADE, related_name='lessons')
teachers = models.ManyToManyField('core.Person', related_name='lessons') teachers = models.ManyToManyField('core.Person', related_name='lessons')
...@@ -99,7 +103,7 @@ class Lesson(models.Model): ...@@ -99,7 +103,7 @@ class Lesson(models.Model):
ordering = ['date_start'] ordering = ['date_start']
class LessonSubstitution(models.Model): class LessonSubstitution(SchoolRelated):
week = models.IntegerField(verbose_name=_('Week'), week = models.IntegerField(verbose_name=_('Week'),
default=current_week) default=current_week)
...@@ -118,14 +122,14 @@ class LessonSubstitution(models.Model): ...@@ -118,14 +122,14 @@ class LessonSubstitution(models.Model):
'lesson_period__period__weekday', 'lesson_period__period__period'] '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') lesson = models.ForeignKey('Lesson', models.CASCADE, related_name='lesson_periods')
period = models.ForeignKey('TimePeriod', 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') room = models.ForeignKey('Room', models.CASCADE, null=True, related_name='lesson_periods')
def get_substitution(self, week: Optional[int] = None) -> LessonSubstitution: 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() return self.substitutions.filter(week=wanted_week).first()
def get_subject(self) -> Optional[Subject]: def get_subject(self) -> Optional[Subject]:
......
...@@ -11,8 +11,21 @@ ...@@ -11,8 +11,21 @@
{% block page_title %}{% blocktrans %}Timetable{% endblocktrans %}{% endblock %} {% block page_title %}{% blocktrans %}Timetable{% endblocktrans %}{% endblock %}
{% block content %} {% 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"> <form method="get">
{% csrf_token %}
<ul id="timetable_select_form"> <ul id="timetable_select_form">
{{ select_form.as_ul }} {{ select_form.as_ul }}
</ul> </ul>
......
...@@ -5,6 +5,7 @@ from . import views ...@@ -5,6 +5,7 @@ from . import views
urlpatterns = [ urlpatterns = [
path('timetable', views.timetable, name='timetable'), 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', views.lessons_day, name='lessons_day'),
path('lessons/<when>', views.lessons_day, name='lessons_day_by_date'), path('lessons/<when>', views.lessons_day, name='lessons_day_by_date'),
path('lessons/<int:id_>/<int:week>/substition', views.edit_substitution, name='edit_substitution') path('lessons/<int:id_>/<int:week>/substition', views.edit_substitution, name='edit_substitution')
......
from collections import OrderedDict
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from collections import OrderedDict
from typing import Optional from typing import Optional
from django.contrib.auth.decorators import login_required 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.http import HttpRequest, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render 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.urls import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_tables2 import RequestConfig from django_tables2 import RequestConfig
from biscuit.core.decorators import admin_required from biscuit.core.decorators import admin_required
...@@ -20,16 +22,22 @@ from .tables import LessonsTable ...@@ -20,16 +22,22 @@ from .tables import LessonsTable
@login_required @login_required
def timetable(request: HttpRequest) -> HttpResponse: @cache_page(60 * 60 * 12)
def timetable(request: HttpRequest, week: Optional[int] = None) -> HttpResponse:
context = {} 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): 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 # Incrementally filter lesson periods by GET parameters
if 'group' in request.GET and request.GET['group']: if 'group' in request.GET and request.GET['group']:
lesson_periods = lesson_periods.filter( 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']: if 'teacher' in request.GET and request.GET['teacher']:
lesson_periods = lesson_periods.filter( lesson_periods = lesson_periods.filter(
lesson__teachers__pk=int(request.GET['teacher'])) lesson__teachers__pk=int(request.GET['teacher']))
...@@ -78,7 +86,9 @@ def timetable(request: HttpRequest) -> HttpResponse: ...@@ -78,7 +86,9 @@ def timetable(request: HttpRequest) -> HttpResponse:
context['lesson_periods'] = OrderedDict(sorted(per_day.items())) context['lesson_periods'] = OrderedDict(sorted(per_day.items()))
context['periods'] = TimePeriod.get_times_dict() context['periods'] = TimePeriod.get_times_dict()
context['weekdays'] = dict(TimePeriod.WEEKDAY_CHOICES) 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 context['select_form'] = select_form
return render(request, 'chronos/tt_week.html', context) 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