Merge branch 'review/pylint' of grimbox.be:Sulley/Ultron
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Gregory Trullemans 2022-01-08 07:13:30 +01:00
commit cb37b56465
40 changed files with 312 additions and 322 deletions

View File

@ -87,7 +87,13 @@ disable=raw-checker-failed,
suppressed-message, suppressed-message,
useless-suppression, useless-suppression,
deprecated-pragma, deprecated-pragma,
use-symbolic-message-instead use-symbolic-message-instead,
empty-docstring,
missing-class-docstring,
missing-module-docstring,
missing-function-docstring,
consider-using-f-string,
duplicate-code,
# Enable the message, report, category or checker with the given id(s). You can # Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option # either give multiple identifier separated by comma (,) or put this option

View File

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View File

@ -15,15 +15,15 @@ class HomeTests(TestCase):
def test_home_view_anonymous_redirected_statuts_code(self): def test_home_view_anonymous_redirected_statuts_code(self):
url = reverse("home") url = reverse("home")
response = self.client.get(url) response = self.client.get(url)
self.assertEquals(response.status_code, 302) self.assertEqual(response.status_code, 302)
def test_home_view_status_code_with_user_connected(self): def test_home_view_status_code_with_user_connected(self):
"""Note: This test will switch to green once we will get rid of whitenoise """Note: This test will switch to green once we will get rid of whitenoise
See https://stackoverflow.com/questions/50658241/django-doesnt-load-static-files-valueerrormissing-staticfiles-manifest-entry See https://stackoverflow.com/questions/50658241/django-doesnt-load-static-files-valueerrormissing-staticfiles-manifest-entry # pylint: disable=line-too-long
""" """
login_result = self.client.login(username="jbond", password="007") self.client.login(username="jbond", password="007")
url = reverse("home") url = reverse("home")
response = self.client.get(url, follow=True) response = self.client.get(url, follow=True)
self.assertEquals(response.status_code, 200) self.assertEqual(response.status_code, 200)

View File

@ -1,10 +1,8 @@
from datetime import datetime, timedelta, date from datetime import datetime
from django.db.models import Q from django.db.models import Q
from django.shortcuts import render from django.shortcuts import render
from django.template import RequestContext
from django.utils import timezone from django.utils import timezone
from django.utils.html import format_html
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -12,7 +10,7 @@ from django.views.decorators.http import require_http_methods
from ultron.objective.models import Routine from ultron.objective.models import Routine
from ultron.profiles.models import Profile from ultron.profiles.models import Profile
from ultron.followup.models import Accident, Skill, MindState, Point from ultron.followup.models import Skill, Point
from ultron.location.models import Place, Club from ultron.location.models import Place, Club
from ultron.people.models import Gymnast from ultron.people.models import Gymnast
from ultron.planning.models import Event from ultron.planning.models import Event
@ -43,8 +41,8 @@ def login(request):
pass pass
request.session["clubid"] = request.POST.get("clubid", None) request.session["clubid"] = request.POST.get("clubid", None)
return HttpResponseRedirect("/") return HttpResponseRedirect("/")
else:
context = {"message": "Account disabled."} context = {"message": "Account disabled."}
else: else:
context = {"message": "Wrong login/password."} context = {"message": "Wrong login/password."}
else: else:
@ -106,7 +104,8 @@ def home(request):
# check if gymnast have point # check if gymnast have point
# --------------------------- # ---------------------------
# 1. récupérer tous les évènements passés # 1. récupérer tous les évènements passés
# 2. pour chaque event, vérifier que tous les gymnastes renseignés dans les participants ont des points associés. # 2. pour chaque event, vérifier que tous les gymnastes renseignés
# dans les participants ont des points associés.
# S'il n'y a pas de point, faire une alerte à l'utilisateur qui se connecte. # S'il n'y a pas de point, faire une alerte à l'utilisateur qui se connecte.
# Check if gymnast have update # Check if gymnast have update

View File

@ -1,5 +1,6 @@
from django.contrib import admin from django.contrib import admin
from django.db.models import fields
from django_extensions.admin import ForeignKeyAutocompleteAdmin
from .models import ( from .models import (
Chrono, Chrono,
@ -12,7 +13,6 @@ from .models import (
HeightWeight, HeightWeight,
Plan Plan
) )
from django_extensions.admin import ForeignKeyAutocompleteAdmin
class ChronoAdmin(ForeignKeyAutocompleteAdmin): class ChronoAdmin(ForeignKeyAutocompleteAdmin):

View File

@ -1,10 +1,7 @@
# coding=UTF-8
from django import forms
from datetime import date from datetime import date
from django.db import models from django import forms
from django.forms import fields, widgets
from .models import ( from .models import (
Chrono, Chrono,
LearnedSkill, LearnedSkill,
@ -114,40 +111,23 @@ class ScoreForm(forms.ModelForm):
"event": forms.HiddenInput(), "event": forms.HiddenInput(),
"routine_type": forms.Select(attrs={"class": "form-control selectpicker"}), "routine_type": forms.Select(attrs={"class": "form-control selectpicker"}),
"point_execution": forms.NumberInput( "point_execution": forms.NumberInput(
attrs={ attrs={"class": "form-control", "placeholder": "xx,xx", "min": "0"}
"class": "form-control",
"placeholder": "xx,xx",
"min": "0"
}
), ),
"point_difficulty": forms.NumberInput( "point_difficulty": forms.NumberInput(
attrs={ attrs={"class": "form-control", "placeholder": "xx,xx", "min": "0"}
"class": "form-control",
"placeholder": "xx,xx",
"min": "0"
}
), ),
"point_time_of_flight": forms.NumberInput( "point_time_of_flight": forms.NumberInput(
attrs={ attrs={"class": "form-control", "placeholder": "xx,xx", "min": "0"}
"class": "form-control",
"placeholder": "xx,xx",
"min": "0"
}
), ),
"point_horizontal_displacement": forms.NumberInput( "point_horizontal_displacement": forms.NumberInput(
attrs={ attrs={"class": "form-control", "placeholder": "x,xx", "min": "0"}
"class": "form-control",
"placeholder": "x,xx",
"min": "0"
}
), ),
"penality": forms.NumberInput( "penality": forms.NumberInput(
attrs={ attrs={
"class": "form-control", "class": "form-control",
"placeholder": "placeholder": "xx,xx",
"xx,xx",
"value": "0", "value": "0",
"min": "0" "min": "0",
} }
), ),
"total": forms.TextInput( "total": forms.TextInput(
@ -201,7 +181,7 @@ class AccidentForm(forms.ModelForm):
"informations": forms.Textarea( "informations": forms.Textarea(
attrs={ attrs={
"class": "form-control", "class": "form-control",
"placeholder": "Informations about accident: context (why, where, …), consequencies, re-education exercices, …", "placeholder": "Informations about accident: context (why, where, …), consequencies, re-education exercices, …", # pylint: disable=line-too-long
} }
), ),
} }
@ -244,16 +224,16 @@ class MindStateForm(forms.ModelForm):
"event": forms.HiddenInput(), "event": forms.HiddenInput(),
"score": forms.NumberInput( "score": forms.NumberInput(
attrs={ attrs={
"class": "form-control", "class": "form-control",
"placeholder": "x", "placeholder": "x",
"min": "0", "min": "0",
"max": "10" "max": "10",
} }
), ),
"informations": forms.Textarea( "informations": forms.Textarea(
attrs={ attrs={
"class": "form-control", "class": "form-control",
"placeholder": "Informations about the psychological state of mind : context (why, where, …), possible consequencies, …", "placeholder": "Informations about the psychological state of mind : context (why, where, …), possible consequencies, …", # pylint: disable=line-too-long
} }
), ),
} }
@ -343,7 +323,7 @@ class HeightWeightForm(forms.ModelForm):
"class": "form-control", "class": "form-control",
"placeholder": "xxx,x", "placeholder": "xxx,x",
"min": "100", "min": "100",
"max": "220" "max": "220",
} }
), ),
"hips_height": forms.NumberInput( "hips_height": forms.NumberInput(
@ -351,7 +331,7 @@ class HeightWeightForm(forms.ModelForm):
"class": "form-control", "class": "form-control",
"placeholder": "xxx,x", "placeholder": "xxx,x",
"min": "50", "min": "50",
"max": "110" "max": "110",
} }
), ),
"weight": forms.NumberInput( "weight": forms.NumberInput(
@ -359,7 +339,7 @@ class HeightWeightForm(forms.ModelForm):
"class": "form-control", "class": "form-control",
"placeholder": "xxx,x", "placeholder": "xxx,x",
"min": "20", "min": "20",
"max": "110" "max": "110",
} }
), ),
} }
@ -378,7 +358,14 @@ class HeightWeightForm(forms.ModelForm):
class NumberOfRoutineDoneForm(forms.ModelForm): class NumberOfRoutineDoneForm(forms.ModelForm):
class Meta: class Meta:
model = NumberOfRoutineDone model = NumberOfRoutineDone
fields = ("gymnast", "routine", "routine_type", "date", "number_of_try", "number_of_successes") fields = (
"gymnast",
"routine",
"routine_type",
"date",
"number_of_try",
"number_of_successes",
)
widgets = { widgets = {
"gymnast": forms.HiddenInput(), "gymnast": forms.HiddenInput(),
"routine": forms.HiddenInput(), "routine": forms.HiddenInput(),
@ -393,7 +380,7 @@ class NumberOfRoutineDoneForm(forms.ModelForm):
"class": "form-control", "class": "form-control",
"placeholder": "x", "placeholder": "x",
"min": "0", "min": "0",
"max": "50" "max": "50",
} }
), ),
"number_of_successes": forms.NumberInput( "number_of_successes": forms.NumberInput(
@ -401,7 +388,7 @@ class NumberOfRoutineDoneForm(forms.ModelForm):
"class": "form-control", "class": "form-control",
"placeholder": "x", "placeholder": "x",
"min": "0", "min": "0",
"max": "50" "max": "50",
} }
), ),
} }
@ -448,7 +435,7 @@ class PlanForm(forms.ModelForm):
"cando": forms.Select(attrs={"class": "form-control selectpicker"}), "cando": forms.Select(attrs={"class": "form-control selectpicker"}),
"is_done": forms.CheckboxInput( "is_done": forms.CheckboxInput(
attrs={"class": "form-control form-check-input ml-0 mt-0"} attrs={"class": "form-control form-check-input ml-0 mt-0"}
) ),
} }
gymnast_related = forms.CharField( gymnast_related = forms.CharField(

View File

@ -1,6 +1,7 @@
from django.db import models
from datetime import date from datetime import date
from django.db.models.deletion import CASCADE
from django.db import models
from ultron.tools.models import Markdownizable from ultron.tools.models import Markdownizable
from ultron.people.models import Gymnast from ultron.people.models import Gymnast

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,6 +1,4 @@
from django.urls import path, re_path from django.urls import path
from ultron.followup.models import MindState
from . import views from . import views
@ -152,4 +150,4 @@ plan_urlpatterns = [
views.plan_create_or_update, views.plan_create_or_update,
name="plan_update", name="plan_update",
), ),
] ]

View File

@ -1,3 +1,5 @@
from datetime import datetime
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
@ -8,6 +10,7 @@ from django.urls import reverse
from ultron.people.models import Gymnast from ultron.people.models import Gymnast
from ultron.planning.models import Event from ultron.planning.models import Event
from ultron.objective.models import Skill from ultron.objective.models import Skill
from .models import ( from .models import (
Plan, Plan,
Point, Point,
@ -18,6 +21,7 @@ from .models import (
HeightWeight, HeightWeight,
NumberOfRoutineDone, NumberOfRoutineDone,
) )
from .forms import ( from .forms import (
PlanForm, PlanForm,
ScoreForm, ScoreForm,
@ -29,9 +33,6 @@ from .forms import (
NumberOfRoutineDoneForm, NumberOfRoutineDoneForm,
) )
from datetime import datetime
import simplejson
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])
@ -65,10 +66,7 @@ def chrono_create_or_update(request, chronoid=None, gymnast_id=None):
data = None data = None
if gymnast_id is not None: if gymnast_id is not None:
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
data = { data = {"gymnast": gymnast_id, "gymnast_related": gymnast}
"gymnast": gymnast_id,
"gymnast_related": gymnast
}
if request.method == "POST": if request.method == "POST":
form = ChronoForm(request.POST, instance=chrono) form = ChronoForm(request.POST, instance=chrono)
@ -87,8 +85,8 @@ def chrono_create_or_update(request, chronoid=None, gymnast_id=None):
return HttpResponseRedirect( return HttpResponseRedirect(
"/gymnast/details/" + str(new_chrono.gymnast.id) + "/" "/gymnast/details/" + str(new_chrono.gymnast.id) + "/"
) )
else:
print(form.errors) print(form.errors)
else: else:
form = ChronoForm(instance=chrono, initial=data) form = ChronoForm(instance=chrono, initial=data)
@ -116,12 +114,12 @@ def gymnast_learn_skill(request):
) )
learned_skill.save() learned_skill.save()
return HttpResponse(status=200) return HttpResponse(status=200)
if gymnast_id:
print("Error : can not link Gymnast and skill. Missing Skill_ID.")
else: else:
if gymnast_id: print("Error : can not link Gymnast and skill. Missing Gymnast_ID.")
print("Error : can not link Gymnast and skill. Missing Skill_ID.") return HttpResponse(status=500)
else:
print("Error : can not link Gymnast and skill. Missing Gymnast_ID.")
return HttpResponse(status=500)
@login_required @login_required
@ -145,9 +143,11 @@ def learnedskill_create_or_update(request, gymnast_id=None):
if form.is_valid(): if form.is_valid():
form.save() form.save()
return HttpResponseRedirect(reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))) return HttpResponseRedirect(
else: reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
print(form.errors) )
print(form.errors)
else: else:
form = LearnedSkillForm(initial=data) form = LearnedSkillForm(initial=data)
@ -173,24 +173,23 @@ def score_create_or_update(request, scoreid=None, gymnast_id=None):
data = None data = None
if gymnast_id is not None: if gymnast_id is not None:
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
data = { data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)}
"gymnast": gymnast_id,
"gymnast_related": str(gymnast)
}
if request.method == "POST": if request.method == "POST":
form = ScoreForm(request.POST, instance=score) form = ScoreForm(request.POST, instance=score)
if form.is_valid(): if form.is_valid():
form.save() form.save()
return HttpResponseRedirect(reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))) return HttpResponseRedirect(
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
)
# return HttpResponseRedirect( # return HttpResponseRedirect(
# "/gymnast/details/" # "/gymnast/details/"
# + str(form.cleaned_data["gymnast"].id) # + str(form.cleaned_data["gymnast"].id)
# + "/" # + "/"
# ) # )
else:
print(form.errors) print(form.errors)
else: else:
form = ScoreForm(instance=score, initial=data) form = ScoreForm(instance=score, initial=data)
@ -210,8 +209,7 @@ def score_listing(request, gymnast_id=None):
if pattern: if pattern:
score_list = Point.objects.filter( score_list = Point.objects.filter(
Q(event__icontains=pattern) Q(event__icontains=pattern) | Q(gymnast__icontains=pattern)
| Q(gymnast__icontains=pattern)
) )
elif gymnast_id: elif gymnast_id:
score_list = Point.objects.filter(gymnast=gymnast_id) score_list = Point.objects.filter(gymnast=gymnast_id)
@ -261,22 +259,20 @@ def accident_create_or_update(request, accidentid=None, gymnast_id=None):
data = None data = None
if gymnast_id is not None: if gymnast_id is not None:
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
data = { data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)}
"gymnast": gymnast_id,
"gymnast_related": str(gymnast)
}
if request.method == "POST": if request.method == "POST":
form = AccidentForm(request.POST, instance=accident) form = AccidentForm(request.POST, instance=accident)
if form.is_valid(): if form.is_valid():
form.save() form.save()
if accidentid: if accidentid:
return HttpResponseRedirect("/accident/" + str(accidentid) + "/") return HttpResponseRedirect("/accident/" + str(accidentid) + "/")
else:
return HttpResponseRedirect("/accident/") return HttpResponseRedirect("/accident/")
else:
print(form.errors) print(form.errors)
else: else:
form = AccidentForm(instance=accident, initial=data) form = AccidentForm(instance=accident, initial=data)
@ -314,32 +310,25 @@ def mindstate_listing(request, gymnast_id=None):
@login_required @login_required
@require_http_methods(["GET", "POST"]) @require_http_methods(["GET", "POST"])
def mindstate_create_or_update(request, mindstateid=None, gymnast_id=None, eventid=None): def mindstate_create_or_update(
request, mindstateid=None, gymnast_id=None, eventid=None
):
""" """
Formulaire de création d'un nouvel accident. Formulaire de création d'un nouvel accident.
""" """
if mindstateid: if mindstateid:
mindstate = get_object_or_404(MindState, pk=mindstateid) mindstate = get_object_or_404(MindState, pk=mindstateid)
data = { data = {"gymnast_related": mindstate.gymnast, "event_related": mindstate.event}
"gymnast_related": mindstate.gymnast,
"event_related": mindstate.event
}
else: else:
mindstate = None mindstate = None
data = None data = None
if gymnast_id is not None: if gymnast_id is not None:
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
data = { data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)}
"gymnast": gymnast_id,
"gymnast_related": str(gymnast)
}
if eventid is not None: if eventid is not None:
event = get_object_or_404(Event, pk=eventid) event = get_object_or_404(Event, pk=eventid)
data = { data = {"event": eventid, "event_related": str(event)}
"event": eventid,
"event_related": str(event)
}
if request.method == "POST": if request.method == "POST":
form = MindStateForm(request.POST, instance=mindstate) form = MindStateForm(request.POST, instance=mindstate)
@ -348,10 +337,10 @@ def mindstate_create_or_update(request, mindstateid=None, gymnast_id=None, event
form.save() form.save()
if mindstateid: if mindstateid:
return HttpResponseRedirect("/mindstate/" + str(mindstateid) + "/") return HttpResponseRedirect("/mindstate/" + str(mindstateid) + "/")
else:
return HttpResponseRedirect(reverse("mindstate_list")) return HttpResponseRedirect(reverse("mindstate_list"))
else:
print(form.errors) print(form.errors)
else: else:
form = MindStateForm(instance=mindstate, initial=data) form = MindStateForm(instance=mindstate, initial=data)
@ -401,25 +390,32 @@ def heightweight_create_or_update(request, heightweight_id=None, gymnast_id=None
heightweight = None heightweight = None
data = None data = None
if gymnast_id: if gymnast_id:
heightweight = HeightWeight.objects.filter(gymnast=gymnast_id).order_by('-date').first() heightweight = (
HeightWeight.objects.filter(gymnast=gymnast_id)
.order_by("-date")
.first()
)
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
data = { data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)}
"gymnast": gymnast_id,
"gymnast_related": str(gymnast)
}
if request.method == "POST": if request.method == "POST":
form = HeightWeightForm(request.POST, instance=heightweight) form = HeightWeightForm(request.POST, instance=heightweight)
if form.is_valid(): if form.is_valid():
form.save() form.save()
return HttpResponseRedirect(reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))) return HttpResponseRedirect(
else: reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
print(form.errors) )
print(form.errors)
else: else:
form = HeightWeightForm(instance=heightweight, initial=data) form = HeightWeightForm(instance=heightweight, initial=data)
context = {"form": form, "gymnast_id": gymnast_id, "heightweight_id": heightweight_id} context = {
"form": form,
"gymnast_id": gymnast_id,
"heightweight_id": heightweight_id,
}
return render(request, "followup/heightweight/create.html", context) return render(request, "followup/heightweight/create.html", context)
@ -451,26 +447,25 @@ def routinedone_create_or_update(request, routinedone_id=None, gymnast_id=None):
"gymnast": routinedone.gymnast.id, "gymnast": routinedone.gymnast.id,
"gymnast_related": str(routinedone.gymnast), "gymnast_related": str(routinedone.gymnast),
"routine": routinedone.routine.id, "routine": routinedone.routine.id,
"routine_related": str(routinedone.routine) "routine_related": str(routinedone.routine),
} }
else: else:
routinedone = None routinedone = None
data = None data = None
if gymnast_id is not None: if gymnast_id is not None:
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
data = { data = {"gymnast": gymnast_id, "gymnast_related": gymnast}
"gymnast": gymnast_id,
"gymnast_related": gymnast
}
if request.method == "POST": if request.method == "POST":
form = NumberOfRoutineDoneForm(request.POST, instance=routinedone) form = NumberOfRoutineDoneForm(request.POST, instance=routinedone)
if form.is_valid(): if form.is_valid():
form.save() form.save()
return HttpResponseRedirect(reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))) return HttpResponseRedirect(
else: reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
print(form.errors) )
print(form.errors)
else: else:
form = NumberOfRoutineDoneForm(instance=routinedone, initial=data) form = NumberOfRoutineDoneForm(instance=routinedone, initial=data)

View File

@ -1,7 +1,6 @@
# coding=UTF-8
from django import forms from django import forms
from datetime import date
from .models import Place from .models import Place

View File

@ -1,4 +1,3 @@
# coding=UTF-8
from django.db import models from django.db import models
@ -55,7 +54,8 @@ class Club(models.Model):
Représente un club. Un club est associé à un lieu. Pour faciliter les filtres, Représente un club. Un club est associé à un lieu. Pour faciliter les filtres,
un club peut être actif ou non. un club peut être actif ou non.
.. todo:: Un club peut avoir plusieurs salle et une salle peut-être louée par plusieurs clubs... M2M ? .. todo:: Un club peut avoir plusieurs salle
et une salle peut-être louée par plusieurs clubs... M2M ?
""" """
class Meta: class Meta:

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,4 +1,3 @@
# coding=UTF-8
from django.urls import path from django.urls import path

View File

@ -1,21 +1,12 @@
from datetime import datetime, timedelta, date from datetime import datetime
from functools import reduce
import operator
import simplejson import simplejson
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Q, Count from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.template import RequestContext
from django.utils.html import format_html
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from ultron.planning.models import (
Event,
)
from .models import ( from .models import (
Club, Club,
Place, Place,
@ -24,7 +15,7 @@ from .models import (
from .forms import PlaceForm from .forms import PlaceForm
def __diffTime(end, start): def __difference_between_times(end, start):
""" """
Prend deux `datetime.time` en paramètre et calcul la différence entre les deux. Prend deux `datetime.time` en paramètre et calcul la différence entre les deux.
""" """
@ -153,11 +144,11 @@ def club_lookup(request):
@login_required @login_required
def chooseStatistics(request): def choose_statistics(request):
""" """
Renvoie la liste des clubs et des saisons pour que l'utilisateur choisisse quelles statistiques il veut voir. Renvoie la liste des clubs et des saisons pour que l'utilisateur
choisisse quelles statistiques il veut voir.
""" """
pass
# year = int(request.GET.get("year", date.today().year)) # year = int(request.GET.get("year", date.today().year))
@ -185,7 +176,6 @@ def club_statistics(request, clubid):
.. todo:: tenir compte de la saison. .. todo:: tenir compte de la saison.
""" """
pass
# courses = Course.objects.filter(club__in=clubid).order_by( # courses = Course.objects.filter(club__in=clubid).order_by(
@ -204,7 +194,9 @@ def club_statistics(request, clubid):
# list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all()) # list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())
# gymnasts.extend(list_of_gymnasts) # gymnasts.extend(list_of_gymnasts)
# nbgymnast = len(list_of_gymnasts) # nbgymnast = len(list_of_gymnasts)
# # gymnasts = set(gymnasts.extend(Gymnast.objects.filter(to_gym__in=course.to_subgroup.all()))) # # gymnasts = set(gymnasts.extend(Gymnast.objects.filter(
# to_gym__in=course.to_subgroup.all()))
# )
# nbhour = __diffTime(course.hour_end, course.hour_begin) # timedelta # nbhour = __diffTime(course.hour_end, course.hour_begin) # timedelta
# totalHoursByWeek += nbhour.seconds # totalHoursByWeek += nbhour.seconds
@ -292,7 +284,8 @@ def club_statistics(request, clubid):
# - gymnastsDict[gymnast.id]["nbattendance"] # - gymnastsDict[gymnast.id]["nbattendance"]
# ) # )
# # tmp = (gymnastsDict[gymnast.id]['nbhourattendance'].days * 24) + (gymnastsDict[gymnast.id]['nbhourattendance'].seconds/3600) # # tmp = (gymnastsDict[gymnast.id]['nbhourattendance'].days * 24)
# + (gymnastsDict[gymnast.id]['nbhourattendance'].seconds/3600)
# gymnastsDict[gymnast.id]["nbhourattendance"] = ( # gymnastsDict[gymnast.id]["nbhourattendance"] = (
# gymnastsDict[gymnast.id]["nbhourattendance"].days * 24 # gymnastsDict[gymnast.id]["nbhourattendance"].days * 24
# ) + (gymnastsDict[gymnast.id]["nbhourattendance"].seconds / 3600) # ) + (gymnastsDict[gymnast.id]["nbhourattendance"].seconds / 3600)

View File

@ -1,8 +1,9 @@
from django.contrib import admin from django.contrib import admin
from .models import Educative, TouchPosition, Skill, Routine, RoutineSkill
from django_extensions.admin import ForeignKeyAutocompleteAdmin from django_extensions.admin import ForeignKeyAutocompleteAdmin
from .models import TouchPosition, Skill, Routine, RoutineSkill
class TouchPositionAdmin(admin.ModelAdmin): class TouchPositionAdmin(admin.ModelAdmin):
model = TouchPosition model = TouchPosition
@ -13,10 +14,10 @@ class TouchPositionAdmin(admin.ModelAdmin):
list_filter = ("allowed_in_competition",) list_filter = ("allowed_in_competition",)
def duplicate_skill(self, SkillAdmin, request, queryset): def duplicate_skill(modeladmin, request, queryset): # pylint: disable=unused-argument
for object in queryset: for obj in queryset:
object.id = None obj.id = None
object.save() obj.save()
class SkillAdmin(ForeignKeyAutocompleteAdmin): class SkillAdmin(ForeignKeyAutocompleteAdmin):
@ -141,4 +142,4 @@ class RoutineSkillAdmin(admin.ModelAdmin):
admin.site.register(TouchPosition, TouchPositionAdmin) admin.site.register(TouchPosition, TouchPositionAdmin)
admin.site.register(Skill, SkillAdmin) admin.site.register(Skill, SkillAdmin)
admin.site.register(Routine, RoutineAdmin) admin.site.register(Routine, RoutineAdmin)
admin.site.register(RoutineSkill, RoutineSkillAdmin) admin.site.register(RoutineSkill, RoutineSkillAdmin)

View File

@ -1,6 +1,6 @@
from django import forms from django import forms
from datetime import date
from .models import Routine, RoutineSkill from .models import Routine
class RoutineForm(forms.ModelForm): class RoutineForm(forms.ModelForm):
@ -24,10 +24,10 @@ class RoutineForm(forms.ModelForm):
"informations": forms.Textarea( "informations": forms.Textarea(
attrs={ attrs={
"class": "form-control", "class": "form-control",
"placeholder": "Informations about the psychological state of mind : context (why, where, …), possible consequencies, …", "placeholder": "Informations about the psychological state of mind : context (why, where, …), possible consequencies, …", # pylint: disable=line-too-long
} }
), ),
"difficulty": forms.HiddenInput(), "difficulty": forms.HiddenInput(),
"level": forms.HiddenInput(), "level": forms.HiddenInput(),
"active": forms.HiddenInput(), "active": forms.HiddenInput(),
} }

View File

@ -1,7 +1,9 @@
from django.db import models from django.db import models
from ultron.tools.models import Markdownizable
from django.db.models import Q, Count from django.db.models import Q, Count
from datetime import date
from ultron.tools.models import Markdownizable
class Educative(Markdownizable): class Educative(Markdownizable):
@ -68,7 +70,7 @@ def get_default_position():
""" """
try: try:
return TouchPosition.objects.get(default=True).id return TouchPosition.objects.get(default=True).id
except: except TouchPosition.DoesNotExist:
return None return None
@ -77,8 +79,13 @@ class Skill(Educative):
Classe représentant une figure (aka un saut acrobatique). Classe représentant une figure (aka un saut acrobatique).
""" """
# SELECT * FROM `objective_skill` WHERE educative_ptr_id NOT IN (SELECT DISTINCT(from_educative_id) FROM `objective_educative_prerequisite`) # SELECT * FROM `objective_skill`
# SELECT * FROM `objective_skill`, `objective_educative` WHERE `objective_educative`.id = `objective_skill`.educative_ptr_id # WHERE educative_ptr_id NOT IN (
# SELECT DISTINCT(from_educative_id) FROM `objective_educative_prerequisite`
# )
#
# SELECT * FROM `objective_skill`, `objective_educative`
# WHERE `objective_educative`.id = `objective_skill`.educative_ptr_id
class Meta: class Meta:
verbose_name = "Skill" verbose_name = "Skill"

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -30,13 +30,6 @@ routine_urlpatterns = [
views.link_skill_to_routine, views.link_skill_to_routine,
name="link_skill_to_routine", name="link_skill_to_routine",
), ),
# # path(r'<int:routineid>/del_skill/<int:skillid>/order/<int:order>/', views.delete_skill_from_routine, name="delete_skill_from_routine"),
# path(
# r"<int:routineid>/order/<int:order>/",
# views.delete_skill_from_routine,
# name="delete_skill_from_routine",
# ),
# path(r"suggest/", views.suggest_routine, name="suggest_routine",),
path(r"", views.routine_listing, name="routine_list"), path(r"", views.routine_listing, name="routine_list"),
path(r"gymnast/<int:gymnast_id>", views.routine_listing, name="routine_list_for_gymnast"), path(r"gymnast/<int:gymnast_id>", views.routine_listing, name="routine_list_for_gymnast"),
] ]

View File

@ -1,17 +1,17 @@
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.http import HttpResponse, HttpResponseRedirect
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views.decorators.http import require_http_methods
from django.urls import reverse from django.urls import reverse
from ultron.people.models import Gymnast
from .models import Skill, Routine, RoutineSkill
from ultron.followup.models import Plan
from .forms import RoutineForm
import simplejson import simplejson
from ultron.people.models import Gymnast
from .forms import RoutineForm
from .models import Skill, Routine, RoutineSkill
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])
@ -27,8 +27,7 @@ def skill_lookup(request):
# Ignore queries shorter than length 2 # Ignore queries shorter than length 2
if pattern is not None and len(pattern) > 2: if pattern is not None and len(pattern) > 2:
model_results = Skill.objects.filter( model_results = Skill.objects.filter(
Q(short_label__icontains=pattern) Q(short_label__icontains=pattern) | Q(long_label__icontains=pattern)
| Q(long_label__icontains=pattern)
) )
results = [ results = [
{"ID": x.id, "Name": str(x), "Notation": x.notation} for x in model_results {"ID": x.id, "Name": str(x), "Notation": x.notation} for x in model_results
@ -52,8 +51,7 @@ def skill_listing(request, field=None, expression=None, value=None, level=None):
if pattern: if pattern:
skill_list = Skill.objects.filter( skill_list = Skill.objects.filter(
Q(long_label__icontains=pattern) Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
| Q(short_label__icontains=pattern)
) )
elif field and expression and value: elif field and expression and value:
kwargs = {"{0}__{1}".format(field, expression): value} kwargs = {"{0}__{1}".format(field, expression): value}
@ -70,9 +68,10 @@ def skill_listing(request, field=None, expression=None, value=None, level=None):
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def skill_details(request, skillid): def skill_details(request, skillid):
""" """Récupère toutes les informations d'un skill.
Récupère toutes les informations d'un skill.
La méthode en profite pour vérifier les champs level, rank, age_boy et age_girl par rapport aux pré-requis. La méthode en profite pour vérifier les champs level, rank, age_boy et age_girl
par rapport aux pré-requis.
:param skillig: id d'un `skill` :param skillig: id d'un `skill`
:type skillid: int :type skillid: int
@ -103,16 +102,14 @@ def skill_details(request, skillid):
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def routine_listing(request, gymnast_id=None): def routine_listing(request, gymnast_id=None):
""" """Récupère la liste des routines suivant un pattern si celui-ci est défini
Récupère la liste des routines (série) suivant un pattern si celui-ci est définit.
""" """
gymnast = None gymnast = None
pattern = request.GET.get("pattern", None) pattern = request.GET.get("pattern", None)
if pattern: if pattern:
routine_list = Routine.objects.filter( routine_list = Routine.objects.filter(
Q(long_label__icontains=pattern) Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
| Q(short_label__icontains=pattern)
) )
else: else:
if gymnast_id: if gymnast_id:
@ -121,7 +118,11 @@ def routine_listing(request, gymnast_id=None):
else: else:
routine_list = Routine.objects.all() routine_list = Routine.objects.all()
context = {"routine_list": routine_list, "gymnast_id": gymnast_id, "gymnast": gymnast} context = {
"routine_list": routine_list,
"gymnast_id": gymnast_id,
"gymnast": gymnast,
}
return render(request, "objectives/routines/list.html", context) return render(request, "objectives/routines/list.html", context)
@ -135,8 +136,7 @@ def routine_lookup(request):
if pattern is not None and len(pattern) >= 3: if pattern is not None and len(pattern) >= 3:
results = Routine.objects.filter( results = Routine.objects.filter(
Q(long_label__icontains=pattern) Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
| Q(short_label__icontains=pattern)
) )
place_list = [{"id": x.id, "label": str(x)} for x in results] place_list = [{"id": x.id, "label": str(x)} for x in results]
@ -231,11 +231,11 @@ def routine_create_or_update(request, routineid=None):
routine = form.save() routine = form.save()
# ici faire un FOR skill in form_skills_list: # ici faire un FOR skill in form_skills_list:
# record.save() # ca sauve le record dans la table RoutineSkill # record.save() # ca sauve le record dans la table RoutineSkill
# something like this : http://stackoverflow.com/questions/3074938/django-m2m-form-save-through-table # something like this : http://stackoverflow.com/questions/3074938/django-m2m-form-save-through-table # pylint: disable=line-too-long
# TO_FRED : can you help me ? # TO_FRED : can you help me ?
return HttpResponseRedirect(reverse("routine_details", args=(routine.pk,))) return HttpResponseRedirect(reverse("routine_details", args=(routine.pk,)))
else:
print(form.errors) print(form.errors)
else: else:
form = RoutineForm(instance=routine) form = RoutineForm(instance=routine)
@ -270,9 +270,5 @@ def link_skill_to_routine(request, routineid, skillid, order):
link, created = RoutineSkill.objects.get_or_create( link, created = RoutineSkill.objects.get_or_create(
routine=routine, skill=skill, rank=order routine=routine, skill=skill, rank=order
) )
# context = {'link':link, 'created':created}
# return render(request, 'compose_routine.html', context)
return HttpResponse(200, (link, created)) return HttpResponse(200, (link, created))
# except:
# return False

View File

@ -1,8 +1,10 @@
from datetime import date
from django.db import models from django.db import models
from django.db.models import Q, Count, Min from django.db.models import Count
import pendulum import pendulum
from datetime import date
from ultron.location.models import Club from ultron.location.models import Club
from ultron.objective.models import Skill from ultron.objective.models import Skill
@ -36,7 +38,7 @@ class Gymnast(Markdownizable):
hours_by_week = models.PositiveSmallIntegerField(verbose_name="# Hours by week") hours_by_week = models.PositiveSmallIntegerField(verbose_name="# Hours by week")
def __str__(self): def __str__(self):
return u"%s %s" % (self.first_name, self.last_name) return "%s %s" % (self.first_name, self.last_name)
@property @property
def next_birthday(self): def next_birthday(self):
@ -152,8 +154,9 @@ class Gymnast(Markdownizable):
def unknown_skill_lte_level(self, max_level_skill): def unknown_skill_lte_level(self, max_level_skill):
""" """
Renvoie la liste des skill inférieurs ou égaux au niveau max que le gymnaste ne sait *pas* faire. Liste des Skill que le gymnaste ne sait PAS faire/
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)
Ces skills sont classé par niveau.
""" """
return Skill.objects.filter(level__lte=max_level_skill).exclude( return Skill.objects.filter(level__lte=max_level_skill).exclude(
known_by__gymnast=self.id known_by__gymnast=self.id
@ -161,8 +164,8 @@ class Gymnast(Markdownizable):
def unknown_skill_gt_level(self, max_level_skill): def unknown_skill_gt_level(self, max_level_skill):
""" """
Renvoie la liste des skill inférieurs ou égaux au niveau max que le gymnaste ne sait *pas* faire. Liste des Skill que le gymnaste ne sait PAS faire,
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) classé par niveau (ayant un niveau inférieur ou égal au niveau max du gym)
""" """
return Skill.objects.filter(level__gt=max_level_skill).exclude( return Skill.objects.filter(level__gt=max_level_skill).exclude(
known_by__gymnast=self.id known_by__gymnast=self.id
@ -177,7 +180,8 @@ class Gymnast(Markdownizable):
def unknown_skill_gt_rank(self, max_rank_skill): def unknown_skill_gt_rank(self, max_rank_skill):
""" """
Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym) Liste des Skill que le gymnaste ne sais PAS faire
(ayant un niveau plus grand que le niveau max du gym)
""" """
return Skill.objects.filter(level__gt=max_rank_skill).exclude( return Skill.objects.filter(level__gt=max_rank_skill).exclude(
known_by__gymnast=self.id known_by__gymnast=self.id
@ -272,15 +276,33 @@ class Gymnast(Markdownizable):
1. on va chercher le niveau maximum de skill que le gymnast sait faire 1. on va chercher le niveau maximum de skill que le gymnast sait faire
2. on va chercher le nombre de skill par niveau que le gymnast sait faire 2. on va chercher le nombre de skill par niveau que le gymnast sait faire
nb_known_skill_by_level = [{'level': 1, 'nb_known_skill': 1}, {'level': 2, 'nb_known_skill': 2}] nb_known_skill_by_level = [
{
'level': 1,
'nb_known_skill': 1
},
{
'level': 2,
'nb_known_skill': 2
}
]
3. si le niveau max est supérieur à 0 3. si le niveau max est supérieur à 0
OUI: OUI:
a. on va chercher le nombre total des skills dont le niveau est inférieur ou égale au niveau max (cf. 1.) a. on va chercher le nombre total des skills dont le niveau
est inférieur ou égale au niveau max (cf. 1.)
b. on va chercher le nombre de skill qu'il y a par niveau : b. on va chercher le nombre de skill qu'il y a par niveau :
[{'level': 1, 'nb_skill': 1}, {'level': 2, 'nb_skill': 1}] [
{
'level': 1, 'nb_skill': 1
},
{
'level': 2, 'nb_skill': 1
}
]
c. Pour chaque élément da la liste obtenue en b : c. Pour chaque élément da la liste obtenue en b :
- si le niveau du skill est le même que le niveau courant ... je sais pas, je comprends plus... - si le niveau du skill est le même que le niveau courant ...
je sais pas, je comprends plus...
- on incrémente j - on incrémente j
NON: NON:
@ -317,7 +339,7 @@ class Gymnast(Markdownizable):
""" """
context = {} context = {}
min_rank_skill = self.min_rank_skill() # min_rank_skill = self.min_rank_skill()
max_rank_skill = self.max_rank_skill() max_rank_skill = self.max_rank_skill()
context["max_rank_skill"] = max_rank_skill context["max_rank_skill"] = max_rank_skill
nb_known_skill_by_rank = self.known_skill_by_rank() nb_known_skill_by_rank = self.known_skill_by_rank()

View File

@ -13,7 +13,7 @@ def generate_level_chart_bar(gymnast_id):
""" """
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
gymnast_known_skills = gymnast.known_skills.count() # gymnast_known_skills = gymnast.known_skills.count()
context = gymnast.get_informations_from_level() context = gymnast.get_informations_from_level()
return context return context

View File

@ -35,11 +35,17 @@ def generate_skill_doughnut(gymnast_id):
.distinct() .distinct()
.count() .count()
) )
nb_skill = Skill.objects.all().count() nb_skill = Skill.objects.all().count()
gymnast_nb_known_skills = ( gymnast_nb_known_skills = (
LearnedSkill.objects.filter(gymnast=gymnast_id).distinct("skill").count() LearnedSkill.objects.filter(gymnast=gymnast_id).distinct("skill").count()
) )
nb_unknown_skill = nb_skill - gymnast_nb_known_skills nb_unknown_skill = nb_skill - gymnast_nb_known_skills
return {"nb_skill_masterised": nb_skill_masterised, "nb_skill_chained": nb_skill_chained, "nb_skill_without_help": nb_skill_without_help, "nb_skill_whith_help": nb_skill_whith_help, "nb_unknown_skill": nb_unknown_skill} return {
"nb_skill_masterised": nb_skill_masterised,
"nb_skill_chained": nb_skill_chained,
"nb_skill_without_help": nb_skill_without_help,
"nb_skill_whith_help": nb_skill_whith_help,
"nb_unknown_skill": nb_unknown_skill,
}

View File

@ -1,49 +1,48 @@
from datetime import datetime from datetime import datetime
from django.test import TestCase from django.test import TestCase
from django.urls import reverse
from ultron.people.models import Gymnast from ultron.people.models import Gymnast
class GymnastTestCase(TestCase): class GymnastTestCase(TestCase):
def test_gymnast_tostring(self): def test_gymnast_tostring(self):
g = Gymnast(last_name="Pauchou", first_name="Fred") gymnast = Gymnast(last_name="Pauchou", first_name="Fred")
self.assertEqual(str(g), "Fred Pauchou") self.assertEqual(str(gymnast), "Fred Pauchou")
def test_gymnaste_get_age(self): def test_gymnaste_get_age(self):
g = Gymnast( gymnast = Gymnast(
last_name="Pauchou", last_name="Pauchou",
first_name="Fred", first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"), birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
) )
self.assertEqual(g.age, 36) self.assertEqual(gymnast.age, 36)
def test_gymnaste_get_next_age(self): def test_gymnaste_get_next_age(self):
g = Gymnast( gymnast = Gymnast(
last_name="Pauchou", last_name="Pauchou",
first_name="Fred", first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"), birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
) )
self.assertEqual(g.next_age, 37) self.assertEqual(gymnast.next_age, 37)
def test_gymnaste_next_birthday(self): def test_gymnaste_next_birthday(self):
g = Gymnast( gymnast = Gymnast(
last_name="Pauchou", last_name="Pauchou",
first_name="Fred", first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"), birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
) )
self.assertEqual(g.next_birthday, datetime.strptime("03/07/2022", "%d/%m/%Y")) self.assertEqual(gymnast.next_birthday, datetime.strptime("03/07/2022", "%d/%m/%Y"))
def test_next_birthday_in_days(self): def test_next_birthday_in_days(self):
g = Gymnast( gymnast = Gymnast(
last_name="Pauchou", last_name="Pauchou",
first_name="Fred", first_name="Fred",
birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"), birthdate=datetime.strptime("03/07/1985", "%d/%m/%Y"),
) )
self.assertEqual(g.next_birthday_in_days, 196) self.assertEqual(gymnast.next_birthday_in_days, 196)
def test_min_rank_skill(self): def test_min_rank_skill(self):
pass pass

View File

@ -1,4 +1,4 @@
from django.urls import path, re_path from django.urls import path
from . import views from . import views

View File

@ -1,15 +1,14 @@
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
from django.db.models import Q, F, Count, Min
from django.contrib import messages
from .models import Gymnast from django.contrib.auth.decorators import login_required
from .forms import GymnastForm from django.db.models import Q, F
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views.decorators.http import require_http_methods
import simplejson
import pendulum
from ultron.followup.models import Event from ultron.followup.models import Event
from ultron.objective.models import Educative
from ultron.followup.forms import GymnastHasRoutineForm from ultron.followup.forms import GymnastHasRoutineForm
from ultron.followup.models import ( from ultron.followup.models import (
Chrono, Chrono,
@ -20,11 +19,10 @@ from ultron.followup.models import (
Accident, Accident,
HeightWeight, HeightWeight,
NumberOfRoutineDone, NumberOfRoutineDone,
Plan
) )
import simplejson from .models import Gymnast
import pendulum from .forms import GymnastForm
@login_required @login_required
@ -80,16 +78,22 @@ def gymnast_details(request, gymnast_id, tab=None):
percentage_known_skill = (nb_known_skill / nb_skill) * 100 percentage_known_skill = (nb_known_skill / nb_skill) * 100
chronos_list = Chrono.objects.filter(gymnast=gymnast_id).order_by("-date")[:10] chronos_list = Chrono.objects.filter(gymnast=gymnast_id).order_by("-date")[:10]
straightjump_score = ( straightjump_score = (
Chrono.objects.filter(gymnast=gymnast_id).filter(chrono_type=0).order_by("-date") Chrono.objects.filter(gymnast=gymnast_id)
.filter(chrono_type=0)
.order_by("-date")
) )
best_straightjump = ( best_straightjump = (
Chrono.objects.filter(gymnast=gymnast_id).filter(chrono_type=0).order_by("-score")[:1] Chrono.objects.filter(gymnast=gymnast_id)
.filter(chrono_type=0)
.order_by("-score")[:1]
) )
best_routine = ( best_routine = (
Chrono.objects.filter(gymnast=gymnast_id).filter(chrono_type=1).order_by("-score")[:1] Chrono.objects.filter(gymnast=gymnast_id)
.filter(chrono_type=1)
.order_by("-score")[:1]
) )
nb_unknown_skill = nb_skill - gymnast_nb_known_skills # nb_unknown_skill = nb_skill - gymnast_nb_known_skills
context = { context = {
"gymnast": gymnast, "gymnast": gymnast,
@ -217,10 +221,18 @@ def gymnast_display_routines(request, gymnast_id):
Tag affichant les séries d'un gymnaste. Tag affichant les séries d'un gymnaste.
""" """
gymnast = get_object_or_404(Gymnast, pk=gymnast_id) gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
ghr_list = gymnast.has_routine.prefetch_related("routine").filter(dateend__isnull=True) ghr_list = gymnast.has_routine.prefetch_related("routine").filter(
routine_done_list = NumberOfRoutineDone.objects.filter(gymnast = gymnast_id).order_by("-date")[:8] dateend__isnull=True
)
routine_done_list = NumberOfRoutineDone.objects.filter(gymnast=gymnast_id).order_by(
"-date"
)[:8]
context = {"ghr_list": ghr_list, "routine_done_list": routine_done_list, "gymnast_id": gymnast_id} context = {
"ghr_list": ghr_list,
"routine_done_list": routine_done_list,
"gymnast_id": gymnast_id,
}
return render(request, "people/gymnasts/list_routine.html", context) return render(request, "people/gymnasts/list_routine.html", context)
@ -243,9 +255,8 @@ def link_routine_to_gymnast(request, gymnast_id=None):
form.save() form.save()
if gymnast_id is not None: if gymnast_id is not None:
return HttpResponseRedirect("/gymnast/details/" + str(gymnast_id) + "/") return HttpResponseRedirect("/gymnast/details/" + str(gymnast_id) + "/")
else:
return HttpResponseRedirect("/gymnast/")
return HttpResponseRedirect("/gymnast/")
else: else:
form = GymnastHasRoutineForm(instance=gymnast, initial=data) form = GymnastHasRoutineForm(instance=gymnast, initial=data)
@ -273,8 +284,8 @@ def gymnast_create_or_update(request, gymnast_id=None):
if gymnast_form.is_valid(): if gymnast_form.is_valid():
gymnast = gymnast_form.save() gymnast = gymnast_form.save()
return HttpResponseRedirect("/gymnast/details/" + str(gymnast.id)) return HttpResponseRedirect("/gymnast/details/" + str(gymnast.id))
else:
print(gymnast_form.errors) print(gymnast_form.errors)
form = GymnastForm(instance=gymnast, initial=data) form = GymnastForm(instance=gymnast, initial=data)
@ -285,9 +296,9 @@ def gymnast_create_or_update(request, gymnast_id=None):
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def gymnast_display_skill(request, gymnast_id): def gymnast_display_skill(request, gymnast_id):
""" """Tag affichant les statistiques de skill d'un gymnaste
Tag affichant les statistiques de skill d'un gymnaste : le nombre de saut qu'il sait faire (total,
par niveau, par rank, ), calcule la complétude, 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) .. 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 et les counts puis, dans le template on parcourt plusieurs fois cette même liste mais on

View File

@ -45,7 +45,7 @@ class EventAdmin(ForeignKeyAutocompleteAdmin):
# filter_horizontal = ('gymnasts',) # filter_horizontal = ('gymnasts',)
class Event_ParticipationAdmin(admin.ModelAdmin): class EventParticipationAdmin(admin.ModelAdmin):
model = Event_Participation model = Event_Participation
fields = ("event", "gymnast", "rank") fields = ("event", "gymnast", "rank")
@ -54,4 +54,4 @@ class Event_ParticipationAdmin(admin.ModelAdmin):
admin.site.register(EventType, EventTypeAdmin) admin.site.register(EventType, EventTypeAdmin)
admin.site.register(Event, EventAdmin) admin.site.register(Event, EventAdmin)
admin.site.register(Event_Participation, Event_ParticipationAdmin) admin.site.register(Event_Participation, EventParticipationAdmin)

View File

@ -1,15 +1,14 @@
from datetime import date from datetime import date
from django import forms from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from ultron.people.models import Gymnast
from .models import Event from .models import Event
class EventForm(forms.ModelForm): class EventForm(forms.ModelForm):
# gymnasts = forms.ModelMultipleChoiceField(queryset=Gymnast.objects.all(), widget=FilteredSelectMultiple('Gymnast(s)', is_stacked=False)) # gymnasts = forms.ModelMultipleChoiceField(queryset=Gymnast.objects.all(),
# widget=FilteredSelectMultiple('Gymnast(s)', is_stacked=False))
class Meta: class Meta:
model = Event model = Event

View File

@ -1,6 +1,5 @@
from datetime import datetime, time from datetime import datetime, time
from django.contrib.auth import get_user_model
from django.db import models from django.db import models
import pendulum import pendulum

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,4 +1,4 @@
from django.urls import path, re_path from django.urls import path
from . import views from . import views

View File

@ -1,9 +1,10 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
import simplejson
# from followup.models import Chrono, Skill # from followup.models import Chrono, Skill
from ultron.people.models import Gymnast from ultron.people.models import Gymnast
@ -17,7 +18,7 @@ from .forms import EventForm
# import pendulum # import pendulum
import simplejson
# import collections # import collections
# import locale # import locale
@ -64,8 +65,8 @@ def event_create_or_update(request, eventid=None):
if event_form.is_valid(): if event_form.is_valid():
event = event_form.save() event = event_form.save()
return HttpResponseRedirect("/event/" + str(event.id) + "/") return HttpResponseRedirect("/event/" + str(event.id) + "/")
else:
print(event_form.errors) print(event_form.errors)
form = EventForm(instance=event, initial=data) form = EventForm(instance=event, initial=data)
@ -89,7 +90,7 @@ def link_gymnast_to_event(request, eventid, gymnastid):
try: try:
gymnast = get_object_or_404(Gymnast, pk=gymnastid) gymnast = get_object_or_404(Gymnast, pk=gymnastid)
event = get_object_or_404(Event, pk=eventid) event = get_object_or_404(Event, pk=eventid)
link = Event_Participation.objects.create(gymnast=gymnast, event=event) Event_Participation.objects.create(gymnast=gymnast, event=event)
except: except:
return HttpResponse(409) return HttpResponse(409)
@ -173,8 +174,8 @@ def event_detail(request, eventid=None):
event = Event.objects.get(pk=eventid) event = Event.objects.get(pk=eventid)
gymnast_list = [] gymnast_list = []
today = timezone.now().date() # today = timezone.now().date()
tohour = timezone.now().time() # tohour = timezone.now().time()
# if event.datebegin.date() > today: # if event.datebegin.date() > today:
# for gymnast in event.gymnasts.all(): # for gymnast in event.gymnasts.all():

View File

@ -1,7 +1,6 @@
# coding=UTF-8
from django import forms from django import forms
from datetime import date
from .models import Profile from .models import Profile

View File

@ -9,7 +9,7 @@ Les profils peuvent enregistrer les informations suivantes:
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db import models from django.db import models
from django.dispatch import receiver
User = get_user_model() User = get_user_model()

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,6 +1,6 @@
"""URLs définissant la gestion des profils utilisateurs.""" """URLs définissant la gestion des profils utilisateurs."""
from django.urls import path, re_path from django.urls import path
from . import views from . import views

View File

@ -2,14 +2,14 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db.models import Q from django.http import HttpResponseRedirect
from django.http import HttpResponseRedirect, HttpResponse from django.shortcuts import render
from django.shortcuts import get_object_or_404, render
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from .forms import ProfileForm from .forms import ProfileForm
from .models import Profile from .models import Profile
User = get_user_model() User = get_user_model()

View File

@ -1,7 +1,6 @@
"""Ensemble des classes d'utilité publique :-)""" """Ensemble des classes d'utilité publique :-)"""
from django.db import models from django.db import models
from datetime import datetime, date, time, timedelta
from django.utils import timezone from django.utils import timezone
import markdown import markdown
@ -135,8 +134,8 @@ class Temporizable(models.Model):
""" """
if rest: if rest:
return get_number_of_weeks_between(the_date, self.dateend.date()) return get_number_of_weeks_between(the_date, self.dateend.date())
else:
return get_number_of_weeks_between(self.datebegin.date(), the_date) return get_number_of_weeks_between(self.datebegin.date(), the_date)
class Markdownizable(models.Model): class Markdownizable(models.Model):

View File

@ -1,6 +1,6 @@
from django import template from django import template
from django.utils.html import format_html from django.utils.html import format_html
from django.urls import resolve, reverse from django.urls import reverse
register = template.Library() register = template.Library()
@ -19,33 +19,32 @@ def menuitem(context, url, css_class, title):
css_class, css_class,
title, title,
) )
else:
if url == "/admin/": if url == "/admin/":
return format_html(
'<li><a href="{}" target="_blank"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)
else:
return format_html(
'<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)
else: # si le contexte est "/"
if context.request.path == url:
return format_html( return format_html(
'<li class="active"><a href="{}"><i class="{}"></i><p>{}</p></a></li>', '<li><a href="{}" target="_blank"><i class="{}"></i><p>{}</p></a></li>',
url, url,
css_class, css_class,
title, title,
) )
else: return format_html(
return format_html(
'<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>', '<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url, url,
css_class, css_class,
title, title,
) )
if context.request.path == url: # si le contexte est "/"
return format_html(
'<li class="active"><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)
return format_html(
'<li><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
url,
css_class,
title,
)