From 16264a86a5a9e0bcdadfda040ee296467f881091 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Thu, 14 Dec 2023 20:56:48 +0100 Subject: [PATCH] implemented teaching unit and absence pages --- Palto/Palto/migrations/0001_initial.py | 166 ------------------ Palto/Palto/templates/Palto/absence.html | 35 ++++ Palto/Palto/templates/Palto/profile.html | 136 +++++++------- .../templates/Palto/teaching_session.html | 6 +- .../Palto/teaching_session_list.html | 2 +- .../Palto/templates/Palto/teaching_unit.html | 60 +++++++ Palto/Palto/urls.py | 9 + Palto/Palto/views.py | 47 ++++- 8 files changed, 222 insertions(+), 239 deletions(-) delete mode 100644 Palto/Palto/migrations/0001_initial.py create mode 100644 Palto/Palto/templates/Palto/absence.html create mode 100644 Palto/Palto/templates/Palto/teaching_unit.html diff --git a/Palto/Palto/migrations/0001_initial.py b/Palto/Palto/migrations/0001_initial.py deleted file mode 100644 index 56a14d7..0000000 --- a/Palto/Palto/migrations/0001_initial.py +++ /dev/null @@ -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), - ), - ] diff --git a/Palto/Palto/templates/Palto/absence.html b/Palto/Palto/templates/Palto/absence.html new file mode 100644 index 0000000..0ade496 --- /dev/null +++ b/Palto/Palto/templates/Palto/absence.html @@ -0,0 +1,35 @@ +{% extends "Palto/base.html" %} + +{% block body %} + {# absence's information #} + + + + + + + + + + + + + + + + + +
Identifiant{{ absence.id }}
Département{{ absence.department }}
Etudiant{{ absence.student }}
Période{{ absence.start }}
{{ absence.end }}
+ + {# absence's message #} +

+ {{ absence.message }} +

+ + {# absence's attachments #} +
+ {% for attachment in absence.attachments.all %} + {{ attachment.content.name }} + {% endfor %} +
+{% endblock %} diff --git a/Palto/Palto/templates/Palto/profile.html b/Palto/Palto/templates/Palto/profile.html index 6ed7d5f..aaf8ad5 100644 --- a/Palto/Palto/templates/Palto/profile.html +++ b/Palto/Palto/templates/Palto/profile.html @@ -2,73 +2,75 @@ {% load dict_tags %} {% block body %} -
- {{ profile.username }} - {{ profile.email }} - {% if profile.is_superuser %}Administrator{% endif %} + {{ profile.username }} + {{ profile.email }} + {% if profile.is_superuser %}Administrator{% endif %} - {# user related departments table #} - - {% for department, profile_department_data in profile_departments_data.items %} - - {# department name #} - - {# relation information #} - + + + + {% endif %} + {% endwith %} + {# user studying groups #} + {% with student_groups=profile_department_data|dict_get:"student_groups" %} + {% if student_groups|length > 0 %} + + + + + {% endif %} + {% endwith %} +
{{ department.name }} - - {# user managing the department #} - {% if profile_department_data|dict_get:"is_manager" %} - - - - + {# user related departments table #} +
Responsable de Département/
+ {% for department, profile_department_data in profile_departments_data.items %} + + {# department name #} + + {# relation information #} + - - {% endfor %} -
{{ department.name }} + + {# user managing the department #} + {% if profile_department_data|dict_get:"is_manager" %} + + + + + {% endif %} + {# user managing units #} + {% with managing_units=profile_department_data|dict_get:"managing_units" %} + {% if managing_units|length > 0 %} + + + + {% endif %} - {# user managing units #} - {% with managing_units=profile_department_data|dict_get:"managing_units" %} - {% if managing_units|length > 0 %} - - - - - {% endif %} - {% endwith %} - {# user teaching units #} - {% with teaching_units=profile_department_data|dict_get:"teaching_units" %} - {% if teaching_units|length > 0 %} - - - - - {% endif %} - {% endwith %} - {# user studying groups #} - {% with student_groups=profile_department_data|dict_get:"student_groups" %} - {% if student_groups|length > 0 %} - - - - - {% endif %} - {% endwith %} -
Responsable de Département/
Responsable d'UE + {% for managing_unit in managing_units %} + + {{ managing_unit.name }} + + {% if not forloop.last %}
{% endif %} + {% endfor %} +
Responsable d'UE - {% for managing_unit in managing_units %} - {{ managing_unit.name }} - {% if not forloop.last %}
{% endif %} - {% endfor %} -
Enseignant - {% for teaching_unit in teaching_units %} - {{ teaching_unit.name }} - {% if not forloop.last %}
{% endif %} - {% endfor %} -
Groupe Étudiant - {% for student_group in student_groups %} - {{ student_group.name }} - {% if not forloop.last %}
{% endif %} - {% endfor %} -
-
- + {% endwith %} + {# user teaching units #} + {% with teaching_units=profile_department_data|dict_get:"teaching_units" %} + {% if teaching_units|length > 0 %} +
Enseignant + {% for teaching_unit in teaching_units %} + + {{ teaching_unit.name }} + + {% if not forloop.last %}
{% endif %} + {% endfor %} +
Groupe Étudiant + {% for student_group in student_groups %} + {{ student_group.name }} + {% if not forloop.last %}
{% endif %} + {% endfor %} +
+ + + {% endfor %} + {% endblock %} diff --git a/Palto/Palto/templates/Palto/teaching_session.html b/Palto/Palto/templates/Palto/teaching_session.html index c71e13d..e61df75 100644 --- a/Palto/Palto/templates/Palto/teaching_session.html +++ b/Palto/Palto/templates/Palto/teaching_session.html @@ -18,7 +18,7 @@ Unité d'Enseignement - {{ session.unit }} + {{ session.unit }} Enseignant @@ -51,9 +51,9 @@ {% endwith %} - {% with absence=session_student_data|dict_get:"attendance" %} + {% with absence=session_student_data|dict_get:"absence" %} {% if absence != None %} - ... + Détails {% endif %} {% endwith %} diff --git a/Palto/Palto/templates/Palto/teaching_session_list.html b/Palto/Palto/templates/Palto/teaching_session_list.html index 6cbf08c..538d830 100644 --- a/Palto/Palto/templates/Palto/teaching_session_list.html +++ b/Palto/Palto/templates/Palto/teaching_session_list.html @@ -17,7 +17,7 @@ {% for session in sessions %} {{ session.short_id }} - {{ session.unit.name }} + {{ session.unit.name }} {{ session.start }}
{{ session.end }} {{ session.teacher }} {{ session.attendances.all|length }} / {{ session.group.students.all|length }} diff --git a/Palto/Palto/templates/Palto/teaching_unit.html b/Palto/Palto/templates/Palto/teaching_unit.html new file mode 100644 index 0000000..bb8f173 --- /dev/null +++ b/Palto/Palto/templates/Palto/teaching_unit.html @@ -0,0 +1,60 @@ +{% extends "Palto/base.html" %} +{% load dict_tags %} + +{% block body %} + {# unit's information #} + + + + + + + + + + + + + + + + + + + + + +
Identifiant{{ unit.id }}
Nom{{ unit.name }}
Département{{ unit.department.name }}
Mail{% if unit.email != None %}{{ unit.email }}{% else %} / {% endif %}
Sessions{{ unit.sessions.all|length }}
+ + {# unit's managers #} + + + + + + + + {% for manager in unit.managers.all %} + + + + {% endfor %} + +
Responsables
{{ manager }}
+ + {# unit's teachers #} + + + + + + + + {% for teacher in unit.teachers.all %} + + + + {% endfor %} + +
Enseignants
{{ teacher }}
+{% endblock %} diff --git a/Palto/Palto/urls.py b/Palto/Palto/urls.py index 357120f..e848bbf 100644 --- a/Palto/Palto/urls.py +++ b/Palto/Palto/urls.py @@ -18,6 +18,15 @@ urlpatterns = [ path("logout/", views.logout_view, name="logout"), path("profile/", views.profile_view, name="my_profile"), path("profile//", views.profile_view, name="profile"), + + # Units + path("teaching_units//", 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_view, name="teaching_session"), + + # Absences + path("absences//", views.absence_view, name="absence"), + # TODO: new absence ] diff --git a/Palto/Palto/views.py b/Palto/Palto/views.py index ead12c6..f7886f5 100644 --- a/Palto/Palto/views.py +++ b/Palto/Palto/views.py @@ -71,6 +71,10 @@ def profile_view(request: WSGIRequest, profile_id: uuid.UUID = None): # get the corresponding user from its 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 profile_departments_data = { 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 def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID): 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): # TODO: syntaxic sugar session.visible_by_user(request.user) return HttpResponseForbidden() @@ -134,8 +158,8 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID): "absence": get_object_or_none( models.Absence.objects, 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() @@ -150,3 +174,22 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID): 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, + ) + )