added create absence page (missing attachments)

This commit is contained in:
Faraphel 2023-12-14 22:56:22 +01:00
parent acc9ee66e7
commit 8db28b9838
14 changed files with 99 additions and 30 deletions

View file

@ -9,7 +9,7 @@ from django.contrib import admin
from . import models
# TODO: plus de list_filter sur "department" ?
# TODO(Faraphel): plus de list_filter sur "department" ?
# Register your models here.

View file

@ -12,7 +12,7 @@ from rest_framework.exceptions import PermissionDenied
from Palto.Palto import models
# TODO: voir les relations inversées ?
# TODO(Faraphel): voir les relations inversées ?
class ModelSerializerContrains(serializers.ModelSerializer):

View file

@ -1,6 +1,26 @@
from django import forms
from Palto.Palto import models
# Users
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
# Objects
class NewAbsenceForm(forms.Form):
department = forms.ModelChoiceField(queryset=None)
start = forms.DateTimeField(widget=forms.TextInput(attrs=dict(type='datetime-local')))
end = forms.DateTimeField(widget=forms.TextInput(attrs=dict(type='datetime-local')))
message = forms.CharField(widget=forms.Textarea)
def __init__(self, student: models.User, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["department"].queryset = student.studying_departments.all()

View file

@ -15,7 +15,7 @@ from django.db import models
from django.db.models import QuerySet, Q, F
# TODO(Raphaël): split permissions from models for readability
# TODO(Faraphel): split permissions from models for readability
class ModelPermissionHelper:

View file

@ -0,0 +1,11 @@
{% extends "Palto/base.html" %}
{% block body %}
<form method="POST">
{% csrf_token %}
<table>
{{ form_new_absence.as_table }}
</table>
<input type="submit" value="Créer">
</form>
{% endblock %}

View file

@ -9,11 +9,11 @@
</tr>
<tr>
<th>Département</th>
<td>{{ absence.department }}</td>
<td><a href="{# TODO(Faraphel): departement #}">{{ absence.department }}</a></td>
</tr>
<tr>
<th>Etudiant</th>
<td>{{ absence.student }}</td>
<th>Étudiant</th>
<td><a href="{% url "Palto:profile" absence.student.id %}">{{ absence.student }}</a></td>
</tr>
<tr>
<th>Période</th>

View file

@ -3,7 +3,9 @@
{% block body %}
<form method="POST">
{% csrf_token %}
{{ form_login }}
<input type="submit" value="Log in">
<table>
{{ form_login.as_table }}
</table>
<input type="submit" value="Se connecter">
</form>
{% endblock %}

View file

@ -29,7 +29,7 @@
<td>Responsable d'UE</td>
<td>
{% for managing_unit in managing_units %}
<a href="{% url "Palto:teaching_unit" managing_unit.id %}">
<a href="{% url "Palto:teaching_unit_view" managing_unit.id %}">
{{ managing_unit.name }}
</a>
{% if not forloop.last %}<br/>{% endif %}
@ -45,7 +45,7 @@
<td>Enseignant</td>
<td>
{% for teaching_unit in teaching_units %}
<a href="{% url "Palto:teaching_unit" teaching_unit.id %}">
<a href="{% url "Palto:teaching_unit_view" teaching_unit.id %}">
{{ teaching_unit.name }}
</a>
{% if not forloop.last %}<br/>{% endif %}

View file

@ -16,8 +16,8 @@
{# show the information for every session #}
{% for session in sessions %}
<tr>
<td><a href="{% url "Palto:teaching_session" session.id %}">{{ session.short_id }}</a></td>
<td><a href="{% url "Palto:teaching_unit" session.unit.id %}">{{ session.unit.name }}</a></td>
<td><a href="{% url "Palto:teaching_session_view" session.id %}">{{ session.short_id }}</a></td>
<td><a href="{% url "Palto:teaching_unit_view" session.unit.id %}">{{ session.unit.name }}</a></td>
<td>{{ session.start }}<br>{{ session.end }}</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>

View file

@ -18,7 +18,7 @@
</tr>
<tr>
<th>Unité d'Enseignement</th>
<td><a href="{% url "Palto:teaching_unit" session.unit.id %}">{{ session.unit }}</a></td>
<td><a href="{% url "Palto:teaching_unit_view" session.unit.id %}">{{ session.unit }}</a></td>
</tr>
<tr>
<th>Enseignant</th>
@ -53,7 +53,7 @@
<td>
{% with absence=session_student_data|dict_get:"absence" %}
{% if absence != None %}
<a href="{% url "Palto:absence" absence.id %}">Détails</a>
<a href="{% url "Palto:absence_view" absence.id %}">Détails</a>
{% endif %}
{% endwith %}
</td>

View file

@ -14,7 +14,7 @@
</tr>
<tr>
<th>Département</th>
<td href="{# TODO: department url #}">{{ unit.department.name }}</td>
<td href="{# TODO(Faraphel): department url #}">{{ unit.department.name }}</td>
</tr>
<tr>
<th>Mail</th>

View file

@ -20,13 +20,13 @@ urlpatterns = [
path("profile/<uuid:profile_id>/", views.profile_view, name="profile"),
# Units
path("teaching_units/<uuid:unit_id>/", views.teaching_unit_view, name="teaching_unit"),
path("teaching_units/view/<uuid:unit_id>/", views.teaching_unit_view, name="teaching_unit_view"),
# Sessions
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/view/<uuid:session_id>/", views.teaching_session_view, name="teaching_session_view"),
# Absences
path("absences/<uuid:absence_id>/", views.absence_view, name="absence"),
# TODO: new absence
path("absences/view/<uuid:absence_id>/", views.absence_view, name="absence_view"),
path("absences/new/", views.new_absence_view, name="absence_new"),
]

View file

@ -8,11 +8,11 @@ from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from django.core.handlers.wsgi import WSGIRequest
from django.core.paginator import Paginator
from django.db import IntegrityError
from django.http import HttpResponseForbidden
from django.shortcuts import render, get_object_or_404, redirect
from Palto.Palto import models
from Palto.Palto.forms import LoginForm
from Palto.Palto import models, forms
from Palto.Palto.utils import get_object_or_none
ELEMENT_PER_PAGE: int = 30
@ -25,7 +25,7 @@ def homepage_view(request: WSGIRequest):
def login_view(request: WSGIRequest):
# create a login form
form_login = LoginForm(request.POST)
form_login = forms.LoginForm(request.POST)
if form_login.is_valid():
# try to authenticate this user with the credentials
@ -125,13 +125,13 @@ def teaching_unit_view(request: WSGIRequest, unit_id: uuid.UUID):
# 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)
# TODO(Faraphel): syntaxic sugar session.visible_by_user(request.user)
return HttpResponseForbidden()
# render the page
return render(
request,
"Palto/teaching_unit.html",
"Palto/teaching_unit_view.html",
context=dict(
unit=unit,
)
@ -144,7 +144,7 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
# 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)
# TODO(Faraphel): syntaxic sugar session.visible_by_user(request.user)
return HttpResponseForbidden()
# prepare the data and the "complex" query for the template
@ -159,7 +159,7 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
models.Absence.objects,
student=student,
start__lte=session.start, end__gte=session.end
), # TODO: property ?
), # TODO(Faraphel): property ?
}
for student in session.group.students.all()
@ -168,7 +168,7 @@ def teaching_session_view(request: WSGIRequest, session_id: uuid.UUID):
# render the page
return render(
request,
"Palto/teaching_session.html",
"Palto/teaching_session_view.html",
context=dict(
session=session,
session_students_data=session_students_data,
@ -182,14 +182,50 @@ def absence_view(request: WSGIRequest, absence_id: uuid.UUID):
# 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)
# TODO(Faraphel): syntaxic sugar session.visible_by_user(request.user)
return HttpResponseForbidden()
# render the page
return render(
request,
"Palto/absence.html",
"Palto/absence_view.html",
context=dict(
absence=absence,
)
)
@login_required
def new_absence_view(request: WSGIRequest):
# check if the user can create an absence
if not models.Absence.can_user_create(request.user):
return HttpResponseForbidden()
# create a form for the new absence
form_new_absence = forms.NewAbsenceForm(request.user, request.POST)
if form_new_absence.is_valid():
try:
models.Absence.objects.create(
student=request.user,
start=form_new_absence.cleaned_data["start"],
end=form_new_absence.cleaned_data["end"],
department=form_new_absence.cleaned_data["department"],
message=form_new_absence.cleaned_data["message"],
)
except IntegrityError:
form_new_absence.add_error(None, "This absence already exists.")
else:
return redirect("Palto:homepage") # TODO(Faraphel): redirect to absence list
# TODO(Faraphel): add attachments to the forms
# render the page
return render(
request,
"Palto/absence_new.html",
context=dict(
form_new_absence=form_new_absence,
)
)

View file

@ -191,7 +191,7 @@ AUTH_USER_MODEL = "Palto.User"
# CORS settings
# TODO(Raphaël): Only in debug !
# TODO(Faraphel): Only in debug !
CORS_ORIGIN_ALLOW_ALL = True