Ultron/people/views.py

430 lines
15 KiB
Python
Raw Normal View History

2021-11-17 10:39:16 +01:00
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.http import HttpResponse, HttpResponseRedirect
2021-12-02 22:01:50 +01:00
from django.db.models import Q, Count, Min
2021-11-17 10:39:16 +01:00
from django.contrib import messages
from .models import Gymnast
from followup.models import Chrono, LearnedSkill, MindState, Skill, Point, Accident
2021-11-17 10:39:16 +01:00
from .forms import GymnastForm
from followup.models import Event
2021-12-02 22:01:50 +01:00
from objective.models import Educative
2021-11-17 10:39:16 +01:00
import simplejson
import pendulum
2021-11-17 10:39:16 +01:00
@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(last_name__icontains=pattern) | Q(first_name__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_listing(request):
"""
Liste tous les gymnasts connus
2021-11-17 10:39:16 +01:00
"""
gymnast_list = Gymnast.objects.all()
context = {'gymnast_list': gymnast_list}
return render(request, "peoples/gymnasts/list.html", context)
2021-11-17 10:39:16 +01:00
@login_required
@require_http_methods(["GET"])
def gymnast_details(request, gymnastid):
"""
Récupère toutes les informations d'un gymnaste.
2021-11-17 10:39:16 +01:00
"""
gymnast = get_object_or_404(Gymnast, pk=gymnastid)
learnedskills_list = LearnedSkill.objects.filter(gymnast=gymnastid).order_by('-date')[:10]
nb_skill = Skill.objects.all().count()
known_skill = LearnedSkill.objects.filter(gymnast=gymnastid).count()
chronos_list = Chrono.objects.filter(gymnast=gymnastid).order_by('-date')[:10]
straightjump_score = Chrono.objects.filter(gymnast=gymnastid).filter(type=0).order_by('-date')
best_straightjump = Chrono.objects.filter(gymnast=gymnastid).filter(type=0).order_by('-score')[:1]
best_routine = Chrono.objects.filter(gymnast=gymnastid).filter(type=1).order_by('-score')[:1]
routine_score = Chrono.objects.filter(gymnast=gymnastid).filter(type=1).order_by('-date')
points_routine_1_list = Point.objects.filter(gymnast=gymnastid).filter(routine_type=0).order_by('-event__datebegin')
points_routine_2_list = Point.objects.filter(gymnast=gymnastid).filter(routine_type=1).order_by('-event__datebegin')
points_routine_final_list = Point.objects.filter(gymnast=gymnastid).filter(routine_type=2).order_by('-event__datebegin')
2021-11-17 10:39:16 +01:00
context = {
'gymnast': gymnast,
'learnedskills_list': learnedskills_list,
'chronos_list': chronos_list,
'straightjump_score': straightjump_score,
'routine_score': routine_score,
'best_routine': best_routine,
'best_straightjump': best_straightjump,
'nb_skill': nb_skill,
'known_skill': known_skill,
'points_routine_1_list': points_routine_1_list,
'points_routine_2_list': points_routine_2_list,
'points_routine_final_list': points_routine_final_list,
2021-11-17 10:39:16 +01:00
}
return render(request, "peoples/gymnasts/details.html", context)
2021-11-17 10:39:16 +01:00
@login_required
@require_http_methods(["GET"])
def gymnast_display_event(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)
context = {
"next_event_list": next_event_list,
"previous_event_list": previous_event_list,
}
2021-12-02 22:01:50 +01:00
return render(request, "peoples/gymnasts/list_event.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_accident(request, gymnastid):
"""
Renvoie deux listes d'évènements : ceux à venir et ceux passés.
"""
accident_list = Accident.objects.filter(gymnast=gymnastid)
context = {
2021-12-02 22:01:50 +01:00
"accident_list": accident_list,
}
2021-12-02 22:01:50 +01:00
return render(request, "peoples/gymnasts/list_accident.html", context)
@login_required
@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(type=0)
chrono_r1 = chrono_list.filter(type=1)
chrono_r2 = chrono_list.filter(type=2)
chrono_rf = chrono_list.filter(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,
}
2021-12-02 22:01:50 +01:00
return render(request, "peoples/gymnasts/list_scores_chronos.html", context)
@login_required
@require_http_methods(["GET"])
def gymnast_display_mindstate(request, gymnastid):
"""
Selectionne tous les scores réalisés par le gymnaste
"""
mindstate_list = MindState.objects.filter(gymnast=gymnastid).order_by("-date")
context = {
"mindstate_list": mindstate_list,
"gymnastid": gymnastid,
}
2021-12-02 22:01:50 +01:00
return render(request, "peoples/gymnasts/list_mindstate.html", context)
2021-11-17 10:39:16 +01:00
@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)
data = {'club_related': gymnast.club}
else:
gymnast = None
data = {}
if request.method == "POST":
gymnast_form = GymnastForm(request.POST, instance=gymnast)
if gymnast_form.is_valid():
gymnast = gymnast_form.save()
return HttpResponseRedirect("/gymnast/details/" + str(gymnast.id))
else:
print(gymnast_form.errors)
form = GymnastForm(instance=gymnast, initial=data)
context = {"form": form, "gymnastid": gymnastid}
2021-12-02 22:01:50 +01:00
return render(request, "peoples/gymnasts/create.html", context)
def __getInformationsFromLevel(gymnast, total_known_skill):
"""
Calcule toutes les statistiques par rapport au niveau.
"""
context = {}
max_level_educative = Skill.objects.filter(known_by__gymnast=gymnast.id).order_by(
"-level"
)[:1]
# Nombre de Skill que le gymnaste sait faire, groupé par niveau
2021-12-03 15:32:10 +01:00
nb_known_skill_by_level = (
2021-12-02 22:01:50 +01:00
Skill.objects.values("level")
.filter(known_by__gymnast=gymnast.id)
.order_by("level")
2021-12-03 15:32:10 +01:00
.annotate(nb_known_skill=Count("id"))
2021-12-02 22:01:50 +01:00
)
if max_level_educative:
# Niveau maximum de l'élève
context["max_level_educative"] = max_level_educative[0].level
# Nombre de Skill qui ont un niveau inférieur ou égal
context["total_skill"] = Skill.objects.filter(
level__lte=context["max_level_educative"]
).count()
# Nombre de Skill qui ont un niveau intérieur ou égal, groupé par niveau
2021-12-03 15:32:10 +01:00
nb_skill_by_level = (
2021-12-02 22:01:50 +01:00
Skill.objects.values("level")
.filter(level__lte=context["max_level_educative"])
.order_by("level")
2021-12-03 15:32:10 +01:00
.annotate(nb_skill=Count("id"))
2021-12-02 22:01:50 +01:00
)
j = 0
tmp = None
percentages = []
2021-12-03 15:32:10 +01:00
for skill in nb_skill_by_level:
2021-12-02 22:01:50 +01:00
tmp = None
2021-12-03 15:32:10 +01:00
if skill["level"] == nb_known_skill_by_level[j]["level"]:
if skill["nb_skill"] != nb_known_skill_by_level[j]["nb_known_skill"]:
2021-12-02 22:01:50 +01:00
tmp = (
skill["level"],
skill["nb_skill"],
2021-12-03 15:32:10 +01:00
nb_known_skill_by_level[j]["nb_known_skill"],
2021-12-02 22:01:50 +01:00
int(
2021-12-03 15:32:10 +01:00
(nb_known_skill_by_level[j]["nb_known_skill"] / skill["nb_skill"])
2021-12-02 22:01:50 +01:00
* 100
),
)
j += 1
else:
tmp = (skill["level"], skill["nb_skill"], 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["max_level_educative"]
).exclude(known_by__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["new_unknown_skill"] = Skill.objects.filter(
level__gt=context["max_level_educative"]
).exclude(known_by__gymnast=gymnast.id)
else:
context["max_level_educative"] = 0
context["total_skill"] = Skill.objects.all().count()
context["new_unknown_skill"] = Skill.objects.all()
# Calcul des statistiques
if context["total_skill"] != 0:
context["completude"] = "%s%%" % (
int((total_known_skill / context["total_skill"]) * 100)
)
context["evaluated_level"] = int(
context["max_level_educative"] * (total_known_skill / context["total_skill"])
)
else:
context["completude"] = 0
context["evaluated_level"] = 0
return context
def __getInformationsFromRank(gymnast, total_known_skill):
"""
Calcule toutes les statistiques par rapport au rang.
"""
context = {}
min_rank = (
Skill.objects.values("rank")
.exclude(known_by__gymnast=gymnast.id)
.order_by("rank")
.aggregate(Min("rank"))["rank__min"]
)
2021-12-03 15:32:10 +01:00
if min_rank is None:
min_rank = 0
2021-12-02 22:01:50 +01:00
# Nombre de Skill que le gymnaste sait faire, groupé par niveau
2021-12-03 15:32:10 +01:00
nb_known_skill_by_rank = (
2021-12-02 22:01:50 +01:00
Skill.objects.values("rank")
.filter(known_by__gymnast=gymnast.id)
.order_by("rank")
2021-12-03 15:32:10 +01:00
.annotate(nb_known_skill=Count("id"))
2021-12-02 22:01:50 +01:00
)
# Rang maximum dans les éducatifs que le gymnaste sait faire
max_rank_educative = Skill.objects.filter(known_by__gymnast=gymnast.id).order_by(
"-rank"
)[:1]
if max_rank_educative:
# Niveau maximum de l'élève
context["max_rank_educative"] = max_rank_educative[0].rank
# Nombre de Skill qui ont un niveau inférieur ou égal
context["total_skill"] = Skill.objects.filter(
level__lte=context["max_rank_educative"]
).count()
# Nombre de Skill qui ont un niveau intérieur ou égal, groupé par niveau
2021-12-03 15:32:10 +01:00
nb_skill_by_rank = (
2021-12-02 22:01:50 +01:00
Skill.objects.values("rank")
.filter(level__lte=context["max_rank_educative"])
.order_by("rank")
2021-12-03 15:32:10 +01:00
.annotate(nb_skill=Count("id"))
2021-12-02 22:01:50 +01:00
)
j = 0
tmp = None
percentages = []
2021-12-03 15:32:10 +01:00
for skill in nb_skill_by_rank:
2021-12-02 22:01:50 +01:00
# les deux lignes ci-derssous doiuvent partir
2021-12-03 15:32:10 +01:00
if j >= nb_known_skill_by_rank.count():
2021-12-02 22:01:50 +01:00
break
tmp = None
2021-12-03 15:32:10 +01:00
if skill["rank"] == nb_known_skill_by_rank[j]["rank"]:
if skill["nb_skill"] != nb_known_skill_by_rank[j]["nb_known_skill"]:
2021-12-02 22:01:50 +01:00
tmp = (
skill["rank"],
skill["nb_skill"],
2021-12-03 15:32:10 +01:00
nb_known_skill_by_rank[j]["nb_known_skill"],
2021-12-02 22:01:50 +01:00
int(
2021-12-03 15:32:10 +01:00
(nb_known_skill_by_rank[j]["nb_known_skill"] / skill["nb_skill"])
2021-12-02 22:01:50 +01:00
* 100
),
)
j += 1
else:
tmp = (skill["rank"], skill["nb_skill"], 0, 0)
if tmp:
percentages.append(tmp)
context["percentages"] = percentages
2021-12-03 15:32:10 +01:00
# 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["skill_by_rank"] = Skill.objects.filter(
2021-12-02 22:01:50 +01:00
level__lte=context["max_rank_educative"]
2021-12-03 15:32:10 +01:00
).exclude(known_by__gymnast=gymnast.id)
2021-12-02 22:01:50 +01:00
2021-12-03 15:32:10 +01:00
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau
# plus grand que le niveau max du gym)
2021-12-02 22:01:50 +01:00
context["new_unknown_skill"] = Skill.objects.filter(
level__gt=context["max_rank_educative"]
2021-12-03 15:32:10 +01:00
).exclude(known_by__gymnast=gymnast.id)
2021-12-02 22:01:50 +01:00
else:
context["max_rank_educative"] = 0
context["total_skill"] = Skill.objects.all().count()
context["new_unknown_skill"] = Skill.objects.all()
# Calcul des statistiques
if context["total_skill"] != 0:
context["completude"] = "%s%%" % (
int((total_known_skill / context["total_skill"]) * 100)
)
context["evaluated_level"] = (min_rank - 1) + (
int(context["max_rank_educative"] * (total_known_skill / context["total_skill"]))
)
else:
context["completude"] = 0
context["evaluated_level"] = 0
return context
@login_required
@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 = {}
context = __getInformationsFromLevel(gymnast, gymnast_known_skills)
context.update(__getInformationsFromRank(gymnast, gymnast_known_skills))
if gymnast.gender:
context["skill_by_age"] = Skill.objects.filter(age_girl__lte=gymnast.age).exclude(
known_by__gymnast=gymnast.id
)
else:
context["skill_by_age"] = Skill.objects.filter(age_boy__lte=gymnast.age).exclude(
known_by__gymnast=gymnast.id
)
context["gymnast"] = gymnast
context["total_known_skill"] = gymnast_known_skills
return render(request, "peoples/gymnasts/statistics.html", context)