609 lines
20 KiB
Python
609 lines
20 KiB
Python
|
# coding=UTF-8
|
||
|
|
||
|
from django.db.models import Q, Count, Min
|
||
|
from django.shortcuts import render, get_object_or_404
|
||
|
from django.template import RequestContext
|
||
|
from django.http import HttpResponseRedirect, HttpResponse
|
||
|
from django.contrib.auth.decorators import login_required
|
||
|
from django.views.decorators.http import require_http_methods
|
||
|
from django.views.decorators.cache import cache_page
|
||
|
|
||
|
import simplejson
|
||
|
import pendulum
|
||
|
|
||
|
from .forms import AccidentForm, GymnastForm, GymnastHasRoutineForm, UserForm
|
||
|
from .models import Gymnast, Accident, CanDoRelation
|
||
|
from planning.models import Event
|
||
|
from planning.views import suggest_program
|
||
|
from objective.models import Educative, Skill, Chrono
|
||
|
from competition.models import Point
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_listing(request):
|
||
|
"""
|
||
|
Récupère la liste des gymnastes suivant un pattern si celui-ci est défini.
|
||
|
"""
|
||
|
pattern = request.GET.get("pattern", None)
|
||
|
|
||
|
if pattern:
|
||
|
gymnasts_list = Gymnast.objects.filter(
|
||
|
Q(user__last_name__icontains=pattern)
|
||
|
| Q(user__first_name__icontains=pattern)
|
||
|
)
|
||
|
else:
|
||
|
gymnasts_list = Gymnast.objects.filter(user__is_active=True)
|
||
|
|
||
|
context = {"gymnasts_list": gymnasts_list}
|
||
|
print(context)
|
||
|
return render(request, "gymnast_list.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_lookup(request):
|
||
|
"""
|
||
|
Récupère la liste des gymnastes à la volée suivant des caractères de
|
||
|
recherche entrés. (min 3 caractères)
|
||
|
"""
|
||
|
|
||
|
results = []
|
||
|
pattern = request.GET.get("pattern", None)
|
||
|
|
||
|
# Ignore queries shorter than length 3
|
||
|
if pattern is not None and len(pattern) > 3:
|
||
|
model_results = Gymnast.objects.filter(
|
||
|
Q(lastname__icontains=pattern) | Q(firstname__icontains=pattern)
|
||
|
)
|
||
|
results = [{"ID": x.id, "Name": str(x)} for x in model_results]
|
||
|
|
||
|
json = simplejson.dumps(results)
|
||
|
return HttpResponse(json, content_type="application/json")
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_detail(request, gymnastid, tab=None):
|
||
|
"""
|
||
|
Récupère toutes les informations d'un gymnaste.
|
||
|
"""
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
context = {"gymnast": gymnast, "tab": tab}
|
||
|
|
||
|
maxLevelEducative = Educative.objects.filter(cando__gymnast=gymnastid).order_by(
|
||
|
"-level"
|
||
|
)[:1]
|
||
|
context["totalKnownSkill"] = CanDoRelation.objects.filter(gymnast=gymnastid).count()
|
||
|
|
||
|
if maxLevelEducative:
|
||
|
context["totalSkill"] = Skill.objects.filter(
|
||
|
level__lte=maxLevelEducative[0].level
|
||
|
).count()
|
||
|
else:
|
||
|
context["totalSkill"] = Skill.objects.all().count()
|
||
|
|
||
|
context["totalUnknownSkill"] = context["totalSkill"] - context["totalKnownSkill"]
|
||
|
context["nbAccident"] = Accident.objects.filter(gymnast=gymnastid).count()
|
||
|
context["nbEvent"] = Event.objects.filter(gymnasts=gymnastid).count()
|
||
|
context["nbChrono"] = Chrono.objects.filter(gymnast=gymnastid).count()
|
||
|
|
||
|
return render(request, "gymnast_details.html", context)
|
||
|
|
||
|
|
||
|
@cache_page(60 * 3)
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_display_routines(request, gymnastid):
|
||
|
"""
|
||
|
Tag affichant les séries d'un gymnaste.
|
||
|
"""
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
ghr_list = gymnast.has_routine.prefetch_related("routine")
|
||
|
context = {"ghr_list": ghr_list, "gymnastid": gymnast.id}
|
||
|
return render(request, "gymnast_routine.html", context)
|
||
|
|
||
|
|
||
|
# @cache_page(60 * 1)
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_display_scores_chrono(request, gymnastid):
|
||
|
"""
|
||
|
Selectionne tous les scores réalisés par le gymnaste
|
||
|
"""
|
||
|
score_list = Point.objects.filter(gymnast=gymnastid).order_by("-event__datebegin")
|
||
|
score_routine1_list = score_list.filter(routine_type=0)
|
||
|
score_routine2_list = score_list.filter(routine_type=1)
|
||
|
score_routine3_list = score_list.filter(routine_type=2)
|
||
|
|
||
|
chrono_list = Chrono.objects.filter(gymnast=gymnastid).order_by("date")
|
||
|
chrono_10c = chrono_list.filter(routine_type=0)
|
||
|
chrono_r1 = chrono_list.filter(routine_type=1)
|
||
|
chrono_r2 = chrono_list.filter(routine_type=2)
|
||
|
chrono_rf = chrono_list.filter(routine_type=3)
|
||
|
|
||
|
context = {
|
||
|
"score_list": score_list,
|
||
|
"score_routine1_list": score_routine1_list,
|
||
|
"score_routine2_list": score_routine2_list,
|
||
|
"score_routine3_list": score_routine3_list,
|
||
|
"chrono_list": chrono_list,
|
||
|
"chrono_10c": chrono_10c,
|
||
|
"chrono_r1": chrono_r1,
|
||
|
"chrono_r2": chrono_r2,
|
||
|
"chrono_rf": chrono_rf,
|
||
|
"gymnastid": gymnastid,
|
||
|
}
|
||
|
|
||
|
return render(request, "gymnast_scores_chrono.html", context)
|
||
|
|
||
|
|
||
|
@cache_page(60 * 5)
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_display_event_accident(request, gymnastid):
|
||
|
"""
|
||
|
Renvoie deux listes d'évènements : ceux à venir et ceux passés.
|
||
|
"""
|
||
|
today = pendulum.now().date()
|
||
|
next_event_list = Event.objects.filter(gymnasts=gymnastid, datebegin__gte=today)
|
||
|
previous_event_list = Event.objects.filter(gymnasts=gymnastid, datebegin__lte=today)
|
||
|
|
||
|
accident_list = Accident.objects.filter(gymnast=gymnastid)
|
||
|
context = {"accidents": accident_list}
|
||
|
|
||
|
context = {
|
||
|
"next_event_list": next_event_list,
|
||
|
"previous_event_list": previous_event_list,
|
||
|
"accidents": accident_list,
|
||
|
}
|
||
|
return render(request, "gymnast_event_accident.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET", "POST"])
|
||
|
def gymnast_create_or_update(request, gymnastid=None):
|
||
|
"""
|
||
|
Formulaire de creation et modification d'un gymnaste.
|
||
|
"""
|
||
|
|
||
|
if gymnastid:
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
else:
|
||
|
gymnast = None
|
||
|
|
||
|
if request.method == "POST":
|
||
|
user_form = UserForm(request.POST, instance=gymnast.user)
|
||
|
user_form["username"] = user_form["first_name"] + "_" + user_form["last_name"]
|
||
|
gymnast_form = GymnastForm(request.POST, instance=gymnast)
|
||
|
|
||
|
if user_form.is_valid():
|
||
|
user = user_form.save()
|
||
|
gymnast_form["user"] = user
|
||
|
|
||
|
if gymnast_form.is_valid():
|
||
|
gymnast = gymnast_form.save()
|
||
|
|
||
|
return HttpResponseRedirect("/gymnast/" + gymnast.id)
|
||
|
|
||
|
else:
|
||
|
form = GymnastForm(instance=gymnast)
|
||
|
|
||
|
context = {"form": form, "gymnastid": gymnastid}
|
||
|
return render(request, "gymnast_create.html", context)
|
||
|
|
||
|
|
||
|
def __getInformationsFromLevel(gymnast, totalKnownSkill):
|
||
|
"""
|
||
|
Calcule toutes les statistiques par rapport au niveau.
|
||
|
"""
|
||
|
|
||
|
context = {}
|
||
|
maxLevelEducative = Educative.objects.filter(cando__gymnast=gymnast.id).order_by(
|
||
|
"-level"
|
||
|
)[:1]
|
||
|
|
||
|
# Nombre de Skill que le gymnaste sait faire, groupé par niveau
|
||
|
nbKnownSkillByLevel = (
|
||
|
Skill.objects.values("level")
|
||
|
.filter(cando__gymnast=gymnast.id)
|
||
|
.order_by("level")
|
||
|
.annotate(nbknownskill=Count("id"))
|
||
|
)
|
||
|
|
||
|
if maxLevelEducative:
|
||
|
# Niveau maximum de l'élève
|
||
|
context["maxLevelEducative"] = maxLevelEducative[0].level
|
||
|
|
||
|
# Nombre de Skill qui ont un niveau inférieur ou égal
|
||
|
context["totalSkill"] = Skill.objects.filter(
|
||
|
level__lte=context["maxLevelEducative"]
|
||
|
).count()
|
||
|
|
||
|
# Nombre de Skill qui ont un niveau intérieur ou égal, groupé par niveau
|
||
|
nbSkillByLevel = (
|
||
|
Skill.objects.values("level")
|
||
|
.filter(level__lte=context["maxLevelEducative"])
|
||
|
.order_by("level")
|
||
|
.annotate(nbskill=Count("id"))
|
||
|
)
|
||
|
|
||
|
j = 0
|
||
|
tmp = None
|
||
|
percentages = []
|
||
|
for skill in nbSkillByLevel:
|
||
|
tmp = None
|
||
|
if skill["level"] == nbKnownSkillByLevel[j]["level"]:
|
||
|
if skill["nbskill"] != nbKnownSkillByLevel[j]["nbknownskill"]:
|
||
|
tmp = (
|
||
|
skill["level"],
|
||
|
skill["nbskill"],
|
||
|
nbKnownSkillByLevel[j]["nbknownskill"],
|
||
|
int(
|
||
|
(nbKnownSkillByLevel[j]["nbknownskill"] / skill["nbskill"])
|
||
|
* 100
|
||
|
),
|
||
|
)
|
||
|
|
||
|
j += 1
|
||
|
else:
|
||
|
tmp = (skill["level"], skill["nbskill"], 0, 0)
|
||
|
|
||
|
if tmp:
|
||
|
percentages.append(tmp)
|
||
|
|
||
|
context["percentages"] = percentages
|
||
|
|
||
|
# Liste des Skill que le gymnaste ne sait PAS faire, classé par niveau (ayant un niveau inférieur ou égal au niveau max du gym)
|
||
|
context["skillByLevel"] = Skill.objects.filter(
|
||
|
level__lte=context["maxLevelEducative"]
|
||
|
).exclude(cando__gymnast=gymnast.id)
|
||
|
|
||
|
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym)
|
||
|
context["newUnknownSkill"] = Skill.objects.filter(
|
||
|
level__gt=context["maxLevelEducative"]
|
||
|
).exclude(cando__gymnast=gymnast.id)
|
||
|
|
||
|
else:
|
||
|
context["maxLevelEducative"] = 0
|
||
|
context["totalSkill"] = Skill.objects.all().count()
|
||
|
context["newUnknownSkill"] = Skill.objects.all()
|
||
|
|
||
|
# Calcul des statistiques
|
||
|
if context["totalSkill"] != 0:
|
||
|
context["completude"] = "%s%%" % (
|
||
|
int((totalKnownSkill / context["totalSkill"]) * 100)
|
||
|
)
|
||
|
context["evaluatedLevel"] = int(
|
||
|
context["maxLevelEducative"] * (totalKnownSkill / context["totalSkill"])
|
||
|
)
|
||
|
else:
|
||
|
context["completude"] = 0
|
||
|
context["evaluatedLevel"] = 0
|
||
|
|
||
|
return context
|
||
|
|
||
|
|
||
|
def __getInformationsFromRank(gymnast, totalKnownSkill):
|
||
|
"""
|
||
|
Calcule toutes les statistiques par rapport au rang.
|
||
|
"""
|
||
|
|
||
|
context = {}
|
||
|
|
||
|
min_rank = (
|
||
|
Skill.objects.values("rank")
|
||
|
.exclude(cando__gymnast=gymnast.id)
|
||
|
.order_by("rank")
|
||
|
.aggregate(Min("rank"))["rank__min"]
|
||
|
)
|
||
|
# print(min_rank)
|
||
|
|
||
|
# Nombre de Skill que le gymnaste sait faire, groupé par niveau
|
||
|
nbKnownSkillByRank = (
|
||
|
Skill.objects.values("rank")
|
||
|
.filter(cando__gymnast=gymnast.id)
|
||
|
.order_by("rank")
|
||
|
.annotate(nbknownskill=Count("id"))
|
||
|
)
|
||
|
|
||
|
# Rang maximum dans les éducatifs que le gymnaste sait faire
|
||
|
maxRankEducative = Educative.objects.filter(cando__gymnast=gymnast.id).order_by(
|
||
|
"-rank"
|
||
|
)[:1]
|
||
|
|
||
|
if maxRankEducative:
|
||
|
# Niveau maximum de l'élève
|
||
|
context["maxRankEducative"] = maxRankEducative[0].rank
|
||
|
|
||
|
# Nombre de Skill qui ont un niveau inférieur ou égal
|
||
|
context["totalSkill"] = Skill.objects.filter(
|
||
|
level__lte=context["maxRankEducative"]
|
||
|
).count()
|
||
|
|
||
|
# Nombre de Skill qui ont un niveau intérieur ou égal, groupé par niveau
|
||
|
nbSkillByRank = (
|
||
|
Skill.objects.values("rank")
|
||
|
.filter(level__lte=context["maxRankEducative"])
|
||
|
.order_by("rank")
|
||
|
.annotate(nbskill=Count("id"))
|
||
|
)
|
||
|
|
||
|
j = 0
|
||
|
tmp = None
|
||
|
percentages = []
|
||
|
for skill in nbSkillByRank:
|
||
|
# les deux lignes ci-derssous doiuvent partir
|
||
|
if j >= nbKnownSkillByRank.count():
|
||
|
break
|
||
|
|
||
|
tmp = None
|
||
|
# print(j)
|
||
|
if skill["rank"] == nbKnownSkillByRank[j]["rank"]:
|
||
|
if skill["nbskill"] != nbKnownSkillByRank[j]["nbknownskill"]:
|
||
|
tmp = (
|
||
|
skill["rank"],
|
||
|
skill["nbskill"],
|
||
|
nbKnownSkillByRank[j]["nbknownskill"],
|
||
|
int(
|
||
|
(nbKnownSkillByRank[j]["nbknownskill"] / skill["nbskill"])
|
||
|
* 100
|
||
|
),
|
||
|
)
|
||
|
|
||
|
j += 1
|
||
|
else:
|
||
|
# print('dans le else')
|
||
|
tmp = (skill["rank"], skill["nbskill"], 0, 0)
|
||
|
|
||
|
if tmp:
|
||
|
percentages.append(tmp)
|
||
|
|
||
|
context["percentages"] = percentages
|
||
|
|
||
|
# Liste des Skill que le gymnaste ne sait PAS faire, classé par niveau (ayant un niveau inférieur ou égal au niveau max du gym)
|
||
|
context["skillByRank"] = Skill.objects.filter(
|
||
|
level__lte=context["maxRankEducative"]
|
||
|
).exclude(cando__gymnast=gymnast.id)
|
||
|
|
||
|
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym)
|
||
|
context["newUnknownSkill"] = Skill.objects.filter(
|
||
|
level__gt=context["maxRankEducative"]
|
||
|
).exclude(cando__gymnast=gymnast.id)
|
||
|
|
||
|
else:
|
||
|
context["maxRankEducative"] = 0
|
||
|
context["totalSkill"] = Skill.objects.all().count()
|
||
|
context["newUnknownSkill"] = Skill.objects.all()
|
||
|
|
||
|
# Calcul des statistiques
|
||
|
if context["totalSkill"] != 0:
|
||
|
context["completude"] = "%s%%" % (
|
||
|
int((totalKnownSkill / context["totalSkill"]) * 100)
|
||
|
)
|
||
|
context["evaluatedLevel"] = (min_rank - 1) + (
|
||
|
int(context["maxRankEducative"] * (totalKnownSkill / context["totalSkill"]))
|
||
|
)
|
||
|
else:
|
||
|
context["completude"] = 0
|
||
|
context["evaluatedLevel"] = 0
|
||
|
|
||
|
return context
|
||
|
|
||
|
|
||
|
# @cache_page(60 * 1)
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_display_stats(request, gymnastid):
|
||
|
"""
|
||
|
Tag affichant les statistiques d'un gymnaste : le nombre de saut qu'il sait faire (total,
|
||
|
par niveau, par rank, …), calcule la complétude, …
|
||
|
|
||
|
.. todo:: Générer UNE fois la liste de skill que le gymnaste ne sait pas faire (1 query)
|
||
|
et les counts puis, dans le template on parcourt plusieurs fois cette même liste mais on
|
||
|
affiche conditionnellement (par age, par rank, ...)
|
||
|
"""
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
# Nombre de Skill que le gymnaste sait faire
|
||
|
gymnast_known_skills = gymnast.known_skills.count()
|
||
|
context = __getInformationsFromLevel(gymnast, gymnast_known_skills)
|
||
|
context.update(__getInformationsFromRank(gymnast, gymnast_known_skills))
|
||
|
|
||
|
if gymnast.gender:
|
||
|
context["skillByAge"] = Skill.objects.filter(ageGirl__lte=gymnast.age).exclude(
|
||
|
cando__gymnast=gymnast.id
|
||
|
)
|
||
|
else:
|
||
|
context["skillByAge"] = Skill.objects.filter(ageBoy__lte=gymnast.age).exclude(
|
||
|
cando__gymnast=gymnast.id
|
||
|
)
|
||
|
|
||
|
context["gymnast"] = gymnast
|
||
|
context["totalKnownSkill"] = gymnast_known_skills
|
||
|
|
||
|
return render(request, "gymnast_statistics.html", context)
|
||
|
|
||
|
|
||
|
@cache_page(60 * 2)
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_display_level(request, gymnastid):
|
||
|
"""
|
||
|
Tag affichant les statistiques d'un gymnaste : le nombre de saut qu'il sait faire (total,
|
||
|
par niveau, par rank, …), calcule la complétude, …
|
||
|
|
||
|
.. todo:: Générer UNE fois la liste de skill que le gymnaste ne sait pas faire (1 query)
|
||
|
et les counts puis, dans le template on parcourt plusieurs fois cette même liste mais on
|
||
|
affiche conditionnellement (par age, par rank, ...)
|
||
|
"""
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
gymnast_known_skills = gymnast.known_skills.count()
|
||
|
context = __getInformationsFromRank(gymnast, gymnast_known_skills)
|
||
|
context["gymnast"] = gymnast
|
||
|
context["totalKnownSkill"] = gymnast_known_skills
|
||
|
|
||
|
if gymnast.gender:
|
||
|
context["skillByAge"] = Skill.objects.filter(ageGirl__lte=gymnast.age).exclude(
|
||
|
cando__gymnast=gymnast.id
|
||
|
)
|
||
|
else:
|
||
|
context["skillByAge"] = Skill.objects.filter(ageBoy__lte=gymnast.age).exclude(
|
||
|
cando__gymnast=gymnast.id
|
||
|
)
|
||
|
|
||
|
return render(request, "gymnast_display_level.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET"])
|
||
|
def gymnast_display_program(request, gymnastid, date=None):
|
||
|
"""Fais une proposition de programme pour le prochain cours si un programme
|
||
|
n'existe pas déjà.
|
||
|
1) trouver la date du prochain cours de l'élève
|
||
|
2) vérifier si un programme existe pour ce cours
|
||
|
2.1) s'il en existe un, aller le chercher pour l'afficher
|
||
|
2.2) s'il n'existe pas, proposer un programme (non validé)
|
||
|
"""
|
||
|
if date is None:
|
||
|
date = pendulum.now().date()
|
||
|
else:
|
||
|
date = pendulum.datetime(date.year(), date.month(), date.day())
|
||
|
iso_day_number = int(date.format("E"))
|
||
|
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
next_course = (
|
||
|
gymnast.courses.filter(iso_day_number__gte=iso_day_number)
|
||
|
.order_by("iso_day_number")
|
||
|
.first()
|
||
|
)
|
||
|
|
||
|
if next_course is None:
|
||
|
next_course = (
|
||
|
gymnast.courses.filter(iso_day_number__gte=0)
|
||
|
.order_by("iso_day_number")
|
||
|
.first()
|
||
|
)
|
||
|
diff = (7 - iso_day_number) + next_course.iso_day_number
|
||
|
else:
|
||
|
diff = iso_day_number - next_course.iso_day_number
|
||
|
|
||
|
course_date = date.add(days=diff)
|
||
|
|
||
|
# dans le cas ou il y a des plusiuers cours le même jours… il faut changer le code !
|
||
|
training = gymnast.trainings.filter(trainingdate=course_date).first()
|
||
|
|
||
|
round_list = None
|
||
|
if training is None:
|
||
|
print("Dans le IF")
|
||
|
round_list = suggest_program(None, gymnastid, date, next_course.duration)
|
||
|
else:
|
||
|
print("Dans le ELSE")
|
||
|
round_list = training.rounds.order_by("round_number")
|
||
|
|
||
|
context = {"course_date": course_date, "round_list": round_list}
|
||
|
return render(request, "gymnast_program.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET", "POST"])
|
||
|
def link_routine_to_gymnast(request, gymnastid=None):
|
||
|
"""
|
||
|
"""
|
||
|
|
||
|
if gymnastid:
|
||
|
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
|
||
|
data = {"gymnast": gymnast.id, "gymnast_related": str(gymnast), "dateend": None}
|
||
|
else:
|
||
|
gymnast = None
|
||
|
data = {"dateend": None}
|
||
|
|
||
|
if request.method == "POST":
|
||
|
print(request.POST)
|
||
|
form = GymnastHasRoutineForm(request.POST)
|
||
|
|
||
|
if form.is_valid():
|
||
|
form.save()
|
||
|
if gymnastid is not None:
|
||
|
return HttpResponseRedirect("/gymnast/" + str(gymnastid) + "/")
|
||
|
else:
|
||
|
return HttpResponseRedirect("/gymnast/")
|
||
|
|
||
|
else:
|
||
|
form = GymnastHasRoutineForm(instance=gymnast, initial=data)
|
||
|
|
||
|
context = {"form": form, "gymnastid": gymnastid}
|
||
|
return render(request, "gymnast_to_routine.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET"])
|
||
|
def accident_listing(request):
|
||
|
"""
|
||
|
Récupère la liste des accidents suivant un pattern si celui-ci est définit.
|
||
|
"""
|
||
|
pattern = request.GET.get("pattern", None)
|
||
|
|
||
|
if pattern:
|
||
|
accident_list = Accident.objects.filter(
|
||
|
Q(gymnast__lastname__icontains=pattern)
|
||
|
| Q(gymnast__firstname__icontains=pattern)
|
||
|
)
|
||
|
else:
|
||
|
accident_list = Accident.objects.all()
|
||
|
|
||
|
context = {"accident_list": accident_list}
|
||
|
return render(request, "accident_list.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET", "POST"])
|
||
|
def accident_create_or_update(request, accidentid=None):
|
||
|
"""
|
||
|
Formulaire de création d'un nouvel accident.
|
||
|
"""
|
||
|
|
||
|
if accidentid:
|
||
|
accident = get_object_or_404(Accident, pk=accidentid)
|
||
|
data = {
|
||
|
"gymnast_related": accident.gymnast,
|
||
|
"educative_related": accident.educative,
|
||
|
}
|
||
|
else:
|
||
|
accident = None
|
||
|
data = {}
|
||
|
|
||
|
if request.method == "POST":
|
||
|
form = AccidentForm(request.POST, instance=accident)
|
||
|
|
||
|
if form.is_valid():
|
||
|
form.save()
|
||
|
if accidentid:
|
||
|
return HttpResponseRedirect("/accident/" + str(accidentid) + "/")
|
||
|
else:
|
||
|
return HttpResponseRedirect("/accident/")
|
||
|
else:
|
||
|
|
||
|
form = AccidentForm(instance=accident, initial=data)
|
||
|
|
||
|
context = {"form": form, "accidentid": accidentid}
|
||
|
return render(request, "accident_create.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
@require_http_methods(["GET"])
|
||
|
def accident_detail(request, accidentid):
|
||
|
"""
|
||
|
Récupère toutes les informations d'un accident.
|
||
|
"""
|
||
|
accident = get_object_or_404(Accident, pk=accidentid)
|
||
|
context = {"accident": accident}
|
||
|
return render(request, "accident_details.html", context)
|
||
|
|
||
|
|
||
|
@login_required
|
||
|
def getRandomKnownSkill(request, gymnastid, numberOfSkill):
|
||
|
"""
|
||
|
Récupére, au hasard, `numberOfSkill` skill que le gymnaste sait déjà faire.
|
||
|
"""
|
||
|
# improvement : http://stackoverflow.com/questions/1731346/how-to-get-two-random-records-with-django/6405601#6405601
|
||
|
skillList = Skill.objects.filter(cando__gymnast=gymnastid).order_by("?")[
|
||
|
0:numberOfSkill
|
||
|
]
|
||
|
context = {"skillList": skillList}
|
||
|
return render(request, "gymnast_details.html", context)
|