implemented teaching unit and absence pages
This commit is contained in:
parent
784d4d4001
commit
16264a86a5
8 changed files with 222 additions and 239 deletions
|
@ -1,166 +0,0 @@
|
||||||
# Generated by Django 4.2.7 on 2023-12-10 11:31
|
|
||||||
|
|
||||||
import Palto.Palto.models
|
|
||||||
from django.conf import settings
|
|
||||||
import django.contrib.auth.models
|
|
||||||
import django.contrib.auth.validators
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import django.utils.timezone
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('auth', '0012_alter_user_first_name_max_length'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Absence',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('message', models.TextField()),
|
|
||||||
('start', models.DateTimeField()),
|
|
||||||
('end', models.DateTimeField()),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Department',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('name', models.CharField(max_length=64, unique=True)),
|
|
||||||
('email', models.EmailField(max_length=254)),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='StudentGroup',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('name', models.CharField(max_length=128)),
|
|
||||||
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_groups', to='Palto.department')),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='User',
|
|
||||||
fields=[
|
|
||||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
|
||||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
|
||||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
|
||||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
|
||||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
|
||||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
|
||||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
|
||||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
|
||||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
|
||||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
|
||||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'user',
|
|
||||||
'verbose_name_plural': 'users',
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
managers=[
|
|
||||||
('objects', django.contrib.auth.models.UserManager()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='TeachingUnit',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('name', models.CharField(max_length=64)),
|
|
||||||
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teaching_units', to='Palto.department')),
|
|
||||||
('managers', models.ManyToManyField(blank=True, related_name='managing_units', to=settings.AUTH_USER_MODEL)),
|
|
||||||
('student_groups', models.ManyToManyField(blank=True, related_name='studying_units', to='Palto.studentgroup')),
|
|
||||||
('teachers', models.ManyToManyField(blank=True, related_name='teaching_units', to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='TeachingSession',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('start', models.DateTimeField()),
|
|
||||||
('duration', models.DurationField()),
|
|
||||||
('note', models.TextField(blank=True)),
|
|
||||||
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teaching_sessions', to='Palto.studentgroup')),
|
|
||||||
('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teaching_sessions', to=settings.AUTH_USER_MODEL)),
|
|
||||||
('unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='Palto.teachingunit')),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='studentgroup',
|
|
||||||
name='owner',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owning_groups', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='studentgroup',
|
|
||||||
name='students',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='student_groups', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='StudentCard',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('uid', models.BinaryField(max_length=7)),
|
|
||||||
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_cards', to='Palto.department')),
|
|
||||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_cards', to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='department',
|
|
||||||
name='managers',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='managing_departments', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='department',
|
|
||||||
name='students',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='studying_departments', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='department',
|
|
||||||
name='teachers',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='teaching_departments', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Attendance',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('date', models.DateTimeField()),
|
|
||||||
('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attendances', to='Palto.teachingsession')),
|
|
||||||
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attended_sessions', to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='AbsenceAttachment',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
|
||||||
('content', models.FileField(upload_to='absence/attachment/')),
|
|
||||||
('absence', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='Palto.absence')),
|
|
||||||
],
|
|
||||||
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='absence',
|
|
||||||
name='department',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='Palto.department'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='absence',
|
|
||||||
name='student',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absences', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
]
|
|
35
Palto/Palto/templates/Palto/absence.html
Normal file
35
Palto/Palto/templates/Palto/absence.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{% extends "Palto/base.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{# absence's information #}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Identifiant</th>
|
||||||
|
<td>{{ absence.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Département</th>
|
||||||
|
<td>{{ absence.department }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Etudiant</th>
|
||||||
|
<td>{{ absence.student }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Période</th>
|
||||||
|
<td>{{ absence.start }}<br>{{ absence.end }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{# absence's message #}
|
||||||
|
<p>
|
||||||
|
{{ absence.message }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{# absence's attachments #}
|
||||||
|
<div>
|
||||||
|
{% for attachment in absence.attachments.all %}
|
||||||
|
<a href="{{ attachment.content.url }}">{{ attachment.content.name }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -2,7 +2,6 @@
|
||||||
{% load dict_tags %}
|
{% load dict_tags %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div>
|
|
||||||
{{ profile.username }}
|
{{ profile.username }}
|
||||||
{{ profile.email }}
|
{{ profile.email }}
|
||||||
{% if profile.is_superuser %}Administrator{% endif %}
|
{% if profile.is_superuser %}Administrator{% endif %}
|
||||||
|
@ -30,7 +29,9 @@
|
||||||
<td>Responsable d'UE</td>
|
<td>Responsable d'UE</td>
|
||||||
<td>
|
<td>
|
||||||
{% for managing_unit in managing_units %}
|
{% for managing_unit in managing_units %}
|
||||||
<a href="{# TODO(Faraphel): redirect to unit #}">{{ managing_unit.name }}</a>
|
<a href="{% url "Palto:teaching_unit" managing_unit.id %}">
|
||||||
|
{{ managing_unit.name }}
|
||||||
|
</a>
|
||||||
{% if not forloop.last %}<br/>{% endif %}
|
{% if not forloop.last %}<br/>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
|
@ -44,7 +45,9 @@
|
||||||
<td>Enseignant</td>
|
<td>Enseignant</td>
|
||||||
<td>
|
<td>
|
||||||
{% for teaching_unit in teaching_units %}
|
{% for teaching_unit in teaching_units %}
|
||||||
<a href="{# TODO(Faraphel): redirect to unit #}">{{ teaching_unit.name }}</a>
|
<a href="{% url "Palto:teaching_unit" teaching_unit.id %}">
|
||||||
|
{{ teaching_unit.name }}
|
||||||
|
</a>
|
||||||
{% if not forloop.last %}<br/>{% endif %}
|
{% if not forloop.last %}<br/>{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
|
@ -70,5 +73,4 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Unité d'Enseignement</th>
|
<th>Unité d'Enseignement</th>
|
||||||
<td>{{ session.unit }}</td>
|
<td><a href="{% url "Palto:teaching_unit" session.unit.id %}">{{ session.unit }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Enseignant</th>
|
<th>Enseignant</th>
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% with absence=session_student_data|dict_get:"attendance" %}
|
{% with absence=session_student_data|dict_get:"absence" %}
|
||||||
{% if absence != None %}
|
{% if absence != None %}
|
||||||
<a href="{# TODO(Raphaël): when absence page added #}">...</a>
|
<a href="{% url "Palto:absence" absence.id %}">Détails</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
{% for session in sessions %}
|
{% for session in sessions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{% url "Palto:teaching_session" session.id %}">{{ session.short_id }}</a></td>
|
<td><a href="{% url "Palto:teaching_session" session.id %}">{{ session.short_id }}</a></td>
|
||||||
<td><a href="{# TODO(Faraphel): add when teaching units #}">{{ session.unit.name }}</a></td>
|
<td><a href="{% url "Palto:teaching_unit" session.unit.id %}">{{ session.unit.name }}</a></td>
|
||||||
<td>{{ session.start }}<br>{{ session.end }}</td>
|
<td>{{ session.start }}<br>{{ session.end }}</td>
|
||||||
<td><a href="{% url "Palto:profile" session.teacher.id %}">{{ session.teacher }}</a></td>
|
<td><a href="{% url "Palto:profile" session.teacher.id %}">{{ session.teacher }}</a></td>
|
||||||
<td>{{ session.attendances.all|length }} / {{ session.group.students.all|length }}</td>
|
<td>{{ session.attendances.all|length }} / {{ session.group.students.all|length }}</td>
|
||||||
|
|
60
Palto/Palto/templates/Palto/teaching_unit.html
Normal file
60
Palto/Palto/templates/Palto/teaching_unit.html
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{% extends "Palto/base.html" %}
|
||||||
|
{% load dict_tags %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{# unit's information #}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Identifiant</th>
|
||||||
|
<td>{{ unit.id }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Nom</th>
|
||||||
|
<td>{{ unit.name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Département</th>
|
||||||
|
<td href="{# TODO: department url #}">{{ unit.department.name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Mail</th>
|
||||||
|
<td>{% if unit.email != None %}{{ unit.email }}{% else %} / {% endif %}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Sessions</th>
|
||||||
|
<td>{{ unit.sessions.all|length }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{# unit's managers #}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Responsables</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for manager in unit.managers.all %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{% url "Palto:profile" manager.id %}">{{ manager }}</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{# unit's teachers #}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Enseignants</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for teacher in unit.teachers.all %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{% url "Palto:profile" teacher.id %}">{{ teacher }}</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
|
@ -18,6 +18,15 @@ urlpatterns = [
|
||||||
path("logout/", views.logout_view, name="logout"),
|
path("logout/", views.logout_view, name="logout"),
|
||||||
path("profile/", views.profile_view, name="my_profile"),
|
path("profile/", views.profile_view, name="my_profile"),
|
||||||
path("profile/<uuid:profile_id>/", views.profile_view, name="profile"),
|
path("profile/<uuid:profile_id>/", views.profile_view, name="profile"),
|
||||||
|
|
||||||
|
# Units
|
||||||
|
path("teaching_units/<uuid:unit_id>/", views.teaching_unit_view, name="teaching_unit"),
|
||||||
|
|
||||||
|
# Sessions
|
||||||
path("teaching_sessions/", views.teaching_session_list_view, name="teaching_session_list"),
|
path("teaching_sessions/", views.teaching_session_list_view, name="teaching_session_list"),
|
||||||
path("teaching_sessions/<uuid:session_id>/", views.teaching_session_view, name="teaching_session"),
|
path("teaching_sessions/<uuid:session_id>/", views.teaching_session_view, name="teaching_session"),
|
||||||
|
|
||||||
|
# Absences
|
||||||
|
path("absences/<uuid:absence_id>/", views.absence_view, name="absence"),
|
||||||
|
# TODO: new absence
|
||||||
]
|
]
|
||||||
|
|
|
@ -71,6 +71,10 @@ def profile_view(request: WSGIRequest, profile_id: uuid.UUID = None):
|
||||||
# get the corresponding user from its id.
|
# get the corresponding user from its id.
|
||||||
profile = get_object_or_404(models.User, id=profile_id)
|
profile = get_object_or_404(models.User, id=profile_id)
|
||||||
|
|
||||||
|
# check if the user is allowed to see this specific object
|
||||||
|
if profile not in models.User.all_visible_by_user(request.user):
|
||||||
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
# prepare the data and the "complex" query for the template
|
# prepare the data and the "complex" query for the template
|
||||||
profile_departments_data = {
|
profile_departments_data = {
|
||||||
department: {
|
department: {
|
||||||
|
@ -115,10 +119,30 @@ def teaching_session_list_view(request: WSGIRequest):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def teaching_unit_view(request: WSGIRequest, unit_id: uuid.UUID):
|
||||||
|
unit = get_object_or_404(models.TeachingUnit, id=unit_id)
|
||||||
|
|
||||||
|
# check if the user is allowed to see this specific object
|
||||||
|
if unit not in models.TeachingUnit.all_visible_by_user(request.user):
|
||||||
|
# TODO: syntaxic sugar session.visible_by_user(request.user)
|
||||||
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
|
# render the page
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"Palto/teaching_unit.html",
|
||||||
|
context=dict(
|
||||||
|
unit=unit,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
|
def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
|
||||||
session = get_object_or_404(models.TeachingSession, id=session_id)
|
session = get_object_or_404(models.TeachingSession, id=session_id)
|
||||||
|
|
||||||
|
# check if the user is allowed to see this specific object
|
||||||
if session not in models.TeachingSession.all_visible_by_user(request.user):
|
if session not in models.TeachingSession.all_visible_by_user(request.user):
|
||||||
# TODO: syntaxic sugar session.visible_by_user(request.user)
|
# TODO: syntaxic sugar session.visible_by_user(request.user)
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
@ -134,8 +158,8 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
|
||||||
"absence": get_object_or_none(
|
"absence": get_object_or_none(
|
||||||
models.Absence.objects,
|
models.Absence.objects,
|
||||||
student=student,
|
student=student,
|
||||||
start__gte=session.start, end__lte=session.end
|
start__lte=session.start, end__gte=session.end
|
||||||
),
|
), # TODO: property ?
|
||||||
}
|
}
|
||||||
|
|
||||||
for student in session.group.students.all()
|
for student in session.group.students.all()
|
||||||
|
@ -150,3 +174,22 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
|
||||||
session_students_data=session_students_data,
|
session_students_data=session_students_data,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def absence_view(request: WSGIRequest, absence_id: uuid.UUID):
|
||||||
|
absence = get_object_or_404(models.Absence, id=absence_id)
|
||||||
|
|
||||||
|
# check if the user is allowed to see this specific object
|
||||||
|
if absence not in models.Absence.all_visible_by_user(request.user):
|
||||||
|
# TODO: syntaxic sugar session.visible_by_user(request.user)
|
||||||
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
|
# render the page
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"Palto/absence.html",
|
||||||
|
context=dict(
|
||||||
|
absence=absence,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue