added create absence page (missing attachments)
This commit is contained in:
parent
acc9ee66e7
commit
8db28b9838
14 changed files with 99 additions and 30 deletions
|
@ -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.
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
11
Palto/Palto/templates/Palto/absence_new.html
Normal file
11
Palto/Palto/templates/Palto/absence_new.html
Normal 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 %}
|
|
@ -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>
|
|
@ -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 %}
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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"),
|
||||
]
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue