Implementation of combination feature
This commit is contained in:
parent
a0fd0faa57
commit
c628816435
|
@ -1,5 +1,5 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q, Count
|
from django.db.models import Q
|
||||||
|
|
||||||
from jarvis.tools.models import Markdownizable, max_even_if_none
|
from jarvis.tools.models import Markdownizable, max_even_if_none
|
||||||
|
|
||||||
|
@ -265,7 +265,17 @@ class Routine(Educative):
|
||||||
return f"{self.long_label} ({self.short_label})"
|
return f"{self.long_label} ({self.short_label})"
|
||||||
|
|
||||||
def compute_informations(self):
|
def compute_informations(self):
|
||||||
"""Calcule les informations (rank, niveau, ages, …) d'une routine."""
|
"""Cette fonction a pour but d'assurer la cohérence des informations d'une combinaison.
|
||||||
|
La fonction vérifie :
|
||||||
|
- les âges pour les filles et garçons,
|
||||||
|
- le rang,
|
||||||
|
- le niveau,
|
||||||
|
- la difficulté
|
||||||
|
- si c'est une routine (série)
|
||||||
|
- si c'est une routine (série) de compétition
|
||||||
|
A chaque fois qu'on le peut, on garde les informations entrées par les utilisateurs néanmoins on vérifie qu'il
|
||||||
|
n'a pas encodé n'importe quoi.
|
||||||
|
"""
|
||||||
rank = 0
|
rank = 0
|
||||||
level = 0
|
level = 0
|
||||||
age_boy_with_help = 0
|
age_boy_with_help = 0
|
||||||
|
@ -277,7 +287,8 @@ class Routine(Educative):
|
||||||
age_boy_masterised = 0
|
age_boy_masterised = 0
|
||||||
age_girl_masterised = 0
|
age_girl_masterised = 0
|
||||||
difficulty = 0
|
difficulty = 0
|
||||||
is_competitive = True
|
is_routine = False
|
||||||
|
is_competitive = False
|
||||||
|
|
||||||
for skill_link in self.skill_links.all():
|
for skill_link in self.skill_links.all():
|
||||||
skill = skill_link.skill
|
skill = skill_link.skill
|
||||||
|
@ -315,8 +326,16 @@ class Routine(Educative):
|
||||||
skill.age_girl_masterised, age_girl_masterised
|
skill.age_girl_masterised, age_girl_masterised
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.skill_links.all().count() != 10:
|
if self.skill_links.all().count() < 5:
|
||||||
|
is_routine = False
|
||||||
is_competitive = False
|
is_competitive = False
|
||||||
|
elif self.skill_links.all().count() != 10:
|
||||||
|
is_competitive = False
|
||||||
|
|
||||||
|
if not self.is_routine:
|
||||||
|
is_competitive = False
|
||||||
|
|
||||||
|
self.is_routine = is_routine
|
||||||
self.is_competitive = is_competitive
|
self.is_competitive = is_competitive
|
||||||
|
|
||||||
self.difficulty = difficulty
|
self.difficulty = difficulty
|
||||||
|
|
|
@ -63,11 +63,11 @@
|
||||||
|
|
||||||
$('body').on('click', '#minusButton', function(event){
|
$('body').on('click', '#minusButton', function(event){
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "{% url 'unlink_skill_from_routine' %}",
|
url: "{% url 'unlink_skill_from_combination' %}",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
routine_id: {{ routine.id }},
|
combination_id: {{ routine.id }},
|
||||||
order: number_of_skill,
|
rank: number_of_skill,
|
||||||
csrfmiddlewaretoken: '{{ csrf_token }}'
|
csrfmiddlewaretoken: '{{ csrf_token }}'
|
||||||
},
|
},
|
||||||
}).done(function() {
|
}).done(function() {
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
url: "{% url 'link_skill_to_combination' %}",
|
url: "{% url 'link_skill_to_combination' %}",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
routine_id: {{ routine.id }},
|
combination_id: {{ routine.id }},
|
||||||
skill_id: ui.item.skillid,
|
skill_id: ui.item.skillid,
|
||||||
rank: number_of_skill,
|
rank: number_of_skill,
|
||||||
csrfmiddlewaretoken: '{{ csrf_token }}'
|
csrfmiddlewaretoken: '{{ csrf_token }}'
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="card-footer row pt-0">
|
<div class="card-footer row pt-0">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<a href="{% url 'routine_list' %}">
|
<a href="{% url 'routine_listing' %}">
|
||||||
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
<button type="submit" value="add" class="btn btn-icon btn-warning ">
|
||||||
<i class="tim-icons icon-double-left"></i>
|
<i class="tim-icons icon-double-left"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="muted-text">There are no events corresponding to your criterias.</p>
|
<p class="muted-text">There are no {{ title|lower }} corresponding to your criterias.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<h4>Prerequisites</h4>
|
<h4>Prerequisites</h4>
|
||||||
<ul>
|
<ul class="pl-4">
|
||||||
{% if skill.prerequisites.all %}
|
{% if skill.prerequisites.all %}
|
||||||
{% for prerequisites in skill.prerequisites.all %}
|
{% for prerequisites in skill.prerequisites.all %}
|
||||||
<li><a href="{% url 'skill_details' prerequisites.id %}">{{ prerequisites.short_label }}</a></li>
|
<li><a href="{% url 'skill_details' prerequisites.id %}">{{ prerequisites.short_label }}</a></li>
|
||||||
|
@ -71,10 +71,23 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<h4>Educatives</h4>
|
<h4>Educatives</h4>
|
||||||
<ul>
|
<ul class="pl-4">
|
||||||
{% if skill.educatives.all %}
|
{% if educative_skill or combination_dict %}
|
||||||
{% for educatives in skill.educatives.all %}
|
{% for skill in educative_skill %}
|
||||||
<li><a href="{% url 'skill_details' educatives.id %}">{{ educatives.short_label }}</a></li>
|
<li><a href="{% url 'skill_details' skill.id %}">
|
||||||
|
{{ skill.short_label }}
|
||||||
|
</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
{% for name, skill_list in combination_dict.items %}
|
||||||
|
<li>
|
||||||
|
{% for skill in skill_list %}
|
||||||
|
<a href="{% url 'skill_details' skill.skill.id %}">{{ skill.skill.short_label }}</a>
|
||||||
|
{% if forloop.last %}
|
||||||
|
{% else %}
|
||||||
|
-
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-muted">No educative defined.</p>
|
<p class="text-muted">No educative defined.</p>
|
||||||
|
|
|
@ -51,7 +51,7 @@ class URLTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/objective/combination/compose/unlink_skill/").view_name,
|
resolve("/objective/combination/compose/unlink_skill/").view_name,
|
||||||
"unlink_skill_from_routine",
|
"unlink_skill_from_combination",
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/combination/competition_routine/").view_name,
|
resolve("/combination/competition_routine/").view_name,
|
||||||
|
|
|
@ -51,8 +51,8 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
r"combination/compose/unlink_skill/",
|
r"combination/compose/unlink_skill/",
|
||||||
views.unlink_skill_from_routine,
|
views.unlink_skill_from_combination,
|
||||||
name="unlink_skill_from_routine",
|
name="unlink_skill_from_combination",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
r"combination/gymnast/<int:gymnast_id>/",
|
r"combination/gymnast/<int:gymnast_id>/",
|
||||||
|
|
|
@ -24,8 +24,7 @@ from .models import (
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def skill_lookup(request):
|
def skill_lookup(request):
|
||||||
"""
|
"""
|
||||||
Récupère la liste des skill à la volée suivant des caractères de
|
Récupère la liste des skill à la volée suivant des caractères de recherche entrés. (min 3 caractères)
|
||||||
recherche entrés. (min 3 caractères)
|
|
||||||
"""
|
"""
|
||||||
results = []
|
results = []
|
||||||
pattern = request.POST.get("pattern", None)
|
pattern = request.POST.get("pattern", None)
|
||||||
|
@ -48,7 +47,7 @@ def skill_lookup(request):
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def skill_without_prerequisite_listing(request):
|
def skill_without_prerequisite_listing(request):
|
||||||
"""
|
"""
|
||||||
Récupère la liste des skills suivant un pattern si celui-ci est définit.
|
Récupère la liste des skills n'ayant aucun prérequis.
|
||||||
"""
|
"""
|
||||||
skill_list = Skill.objects.filter(prerequisites=None)
|
skill_list = Skill.objects.filter(prerequisites=None)
|
||||||
context = {"skill_list": skill_list}
|
context = {"skill_list": skill_list}
|
||||||
|
@ -60,6 +59,12 @@ def skill_without_prerequisite_listing(request):
|
||||||
def skill_listing(request, field=None, expression=None, value=None, level=None):
|
def skill_listing(request, field=None, expression=None, value=None, level=None):
|
||||||
"""
|
"""
|
||||||
Récupère la liste des skills suivant un pattern si celui-ci est définit.
|
Récupère la liste des skills suivant un pattern si celui-ci est définit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
field <str> champ sur lequel doit être effectué la recherche
|
||||||
|
expression <str> expression de comparaison : le, leq, ge, geq, …
|
||||||
|
value <str> valeur de la recherche
|
||||||
|
level <int> niveau requis pour les skills cherchés.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pattern = None
|
pattern = None
|
||||||
|
@ -86,7 +91,11 @@ 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_tree(request, skill_id):
|
def skill_tree(request, skill_id):
|
||||||
""" """
|
"""Récupère tout l'arbre des prérequis pour une saut passé en paramètre
|
||||||
|
|
||||||
|
Args:
|
||||||
|
skill_id <int> identifiant de la classe Skill
|
||||||
|
"""
|
||||||
skill = get_object_or_404(Skill, pk=skill_id)
|
skill = get_object_or_404(Skill, pk=skill_id)
|
||||||
node_dict = {}
|
node_dict = {}
|
||||||
skill_closure = PrerequisiteClosure.objects.filter(descendant=skill)
|
skill_closure = PrerequisiteClosure.objects.filter(descendant=skill)
|
||||||
|
@ -105,10 +114,8 @@ def skill_details(request, skill_id):
|
||||||
La méthode en profite pour vérifier les champs level, rank, age_boy et age_girl
|
La méthode en profite pour vérifier les champs level, rank, age_boy et age_girl
|
||||||
par rapport aux pré-requis.
|
par rapport aux pré-requis.
|
||||||
|
|
||||||
:param skill_id: id d'un `skill`
|
Args:
|
||||||
:type skill_id: int
|
skill_id <int> identifiant de la classe Skill
|
||||||
|
|
||||||
:return: skill
|
|
||||||
"""
|
"""
|
||||||
skill = get_object_or_404(Skill, pk=skill_id)
|
skill = get_object_or_404(Skill, pk=skill_id)
|
||||||
|
|
||||||
|
@ -142,7 +149,22 @@ def skill_details(request, skill_id):
|
||||||
|
|
||||||
skill.save()
|
skill.save()
|
||||||
|
|
||||||
context = {"skill": skill}
|
# Je sépare les educatifs de type "skill" et les éducatifs de type "combination" pour mieux gérer l'affichage
|
||||||
|
# Du code bien dégueulasse !
|
||||||
|
# QTF : une idée pour faire ca de manière plus propre, plus élégante ?
|
||||||
|
combination_dict = {}
|
||||||
|
educative_skill = skill.educatives.filter(id__in=(Skill.objects.all()))
|
||||||
|
for educative in skill.educatives.filter(id__in=(Routine.objects.all())):
|
||||||
|
combination = Routine.objects.get(pk=educative.id)
|
||||||
|
combination_dict[combination] = []
|
||||||
|
for educ_skill in combination.routine.skill_links.all():
|
||||||
|
combination_dict[combination].append(educ_skill)
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"skill": skill,
|
||||||
|
"combination_dict": combination_dict,
|
||||||
|
"educative_skill": educative_skill,
|
||||||
|
}
|
||||||
return render(request, "skills/details.html", context)
|
return render(request, "skills/details.html", context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,11 +199,15 @@ def skill_create_or_update(request, skill_id=None):
|
||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def competition_routine_listing(request, gymnast_id=None):
|
def competition_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éries) de compétition suivant un pattern si celui-ci est défini
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> identifiant de la classe Gymnast
|
||||||
|
"""
|
||||||
|
|
||||||
gymnast = None
|
gymnast = None
|
||||||
pattern = request.GET.get("pattern", None)
|
pattern = request.GET.get("pattern", None)
|
||||||
if pattern:
|
if pattern is not None and len(pattern) > 2:
|
||||||
routine_list = Routine.objects.filter(
|
routine_list = Routine.objects.filter(
|
||||||
is_routine=True, is_competitive=True
|
is_routine=True, is_competitive=True
|
||||||
).filter(Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern))
|
).filter(Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern))
|
||||||
|
@ -206,11 +232,15 @@ def competition_routine_listing(request, gymnast_id=None):
|
||||||
@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éfini
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> identifiant de la classe Gymnast
|
||||||
|
"""
|
||||||
|
|
||||||
gymnast = None
|
gymnast = None
|
||||||
pattern = request.GET.get("pattern", None)
|
pattern = request.GET.get("pattern", None)
|
||||||
if pattern:
|
if pattern is not None and len(pattern) > 2:
|
||||||
routine_list = Routine.objects.filter(is_routine=True).filter(
|
routine_list = Routine.objects.filter(is_routine=True).filter(
|
||||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||||
)
|
)
|
||||||
|
@ -235,11 +265,15 @@ def routine_listing(request, gymnast_id=None):
|
||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def educative_combination_listing(request, gymnast_id=None):
|
def educative_combination_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 educatifs suivant un pattern si celui-ci est défini
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> identifiant de la classe Gymnast
|
||||||
|
"""
|
||||||
|
|
||||||
gymnast = None
|
gymnast = None
|
||||||
pattern = request.GET.get("pattern", None)
|
pattern = request.GET.get("pattern", None)
|
||||||
if pattern:
|
if pattern is not None and len(pattern) > 2:
|
||||||
routine_list = Routine.objects.filter(is_routine=False).filter(
|
routine_list = Routine.objects.filter(is_routine=False).filter(
|
||||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||||
)
|
)
|
||||||
|
@ -264,11 +298,15 @@ def educative_combination_listing(request, gymnast_id=None):
|
||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def combination_listing(request, gymnast_id=None):
|
def combination_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 combinaisons suivant un pattern si celui-ci est défini
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> identifiant de la classe Gymnast
|
||||||
|
"""
|
||||||
|
|
||||||
gymnast = None
|
gymnast = None
|
||||||
pattern = request.GET.get("pattern", None)
|
pattern = request.GET.get("pattern", None)
|
||||||
if pattern:
|
if pattern is not None and len(pattern) > 2:
|
||||||
routine_list = Routine.objects.filter(
|
routine_list = Routine.objects.filter(
|
||||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||||
)
|
)
|
||||||
|
@ -292,11 +330,11 @@ def combination_listing(request, gymnast_id=None):
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def routine_lookup(request):
|
def routine_lookup(request):
|
||||||
"""
|
"""
|
||||||
Récupère la liste des lieux à la volée suivant des caractères de recherche entrés.
|
Récupère la liste des combinaison à la volée suivant des caractères de recherche entrés.
|
||||||
"""
|
"""
|
||||||
pattern = request.POST.get("pattern", None)
|
pattern = request.POST.get("pattern", None)
|
||||||
|
|
||||||
if pattern is not None and len(pattern) >= 3:
|
if pattern is not None and len(pattern) > 2:
|
||||||
results = Routine.objects.filter(
|
results = Routine.objects.filter(
|
||||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||||
)
|
)
|
||||||
|
@ -306,12 +344,13 @@ def routine_lookup(request):
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@require_http_methods(["GET"])
|
||||||
def combination_details(request, combination_id):
|
def combination_details(request, combination_id):
|
||||||
"""
|
"""
|
||||||
Récupère toutes les informations d'une routine (série).
|
Récupère toutes les informations d'une combinaison.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
combination_id int identifiant d'une routine
|
combination_id <int> identifiant d'une routine
|
||||||
"""
|
"""
|
||||||
|
|
||||||
routine = get_object_or_404(Routine, pk=combination_id)
|
routine = get_object_or_404(Routine, pk=combination_id)
|
||||||
|
@ -403,13 +442,13 @@ def link_skill_to_combination(request):
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def unlink_skill_from_routine(request):
|
def unlink_skill_from_combination(request):
|
||||||
"""
|
"""
|
||||||
Recoit dans request deux informations permettant d'enlever un skill d'une routine :
|
Recoit dans request deux informations permettant d'enlever un skill d'une routine :
|
||||||
- order <int> numéro de place du skill dans la routine
|
- rank <int> numéro de place du skill dans la routine
|
||||||
- combination_id <int> identifiant d'un object de classe <routine>
|
- combination_id <int> identifiant d'un object de classe <routine>
|
||||||
"""
|
"""
|
||||||
rank = request.POST.get("order", None)
|
rank = request.POST.get("rank", None)
|
||||||
combination_id = request.POST.get("combination_id", None)
|
combination_id = request.POST.get("combination_id", None)
|
||||||
combination = get_object_or_404(Routine, pk=combination_id)
|
combination = get_object_or_404(Routine, pk=combination_id)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -70,7 +70,7 @@ def gymnast_lookup(request):
|
||||||
results = []
|
results = []
|
||||||
pattern = request.POST.get("pattern", None)
|
pattern = request.POST.get("pattern", None)
|
||||||
|
|
||||||
if pattern is not None and len(pattern) > 3:
|
if pattern is not None and len(pattern) > 2:
|
||||||
model_results = Gymnast.objects.filter(
|
model_results = Gymnast.objects.filter(
|
||||||
Q(last_name__icontains=pattern) | Q(first_name__icontains=pattern)
|
Q(last_name__icontains=pattern) | Q(first_name__icontains=pattern)
|
||||||
)
|
)
|
||||||
|
@ -331,6 +331,9 @@ def gymnast_display_mindstate(request, gymnast_id):
|
||||||
def gymnast_display_routine_statistics(request, gymnast_id):
|
def gymnast_display_routine_statistics(request, gymnast_id):
|
||||||
"""
|
"""
|
||||||
Tag affichant les statistiques et informations de séries d'un gymnaste.
|
Tag affichant les statistiques et informations de séries d'un gymnaste.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> identifiant de la classe Gymnast
|
||||||
"""
|
"""
|
||||||
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(
|
ghr_list = gymnast.has_routine.prefetch_related("routine").filter(
|
||||||
|
@ -369,7 +372,11 @@ def gymnast_display_routine_statistics(request, gymnast_id):
|
||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def link_routine_to_gymnast(request, gymnast_id=None):
|
def link_routine_to_gymnast(request, gymnast_id=None):
|
||||||
""" """
|
"""Lie une série à un gymnaste
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> identifiant de la classe Gymnast
|
||||||
|
"""
|
||||||
|
|
||||||
if gymnast_id:
|
if gymnast_id:
|
||||||
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
|
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
|
||||||
|
@ -423,7 +430,10 @@ def link_routine_to_gymnast(request, gymnast_id=None):
|
||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def gymnast_create_or_update(request, gymnast_id=None):
|
def gymnast_create_or_update(request, gymnast_id=None):
|
||||||
"""
|
"""
|
||||||
Formulaire de creation et modification d'un gymnaste.
|
Formulaire de création et modification d'un gymnaste.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
gymnast_id <int> Identifiant de la classe Gymnast
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if gymnast_id:
|
if gymnast_id:
|
||||||
|
|
Loading…
Reference in New Issue