Compare commits
3 Commits
master
...
training_m
Author | SHA1 | Date |
---|---|---|
Gregory Trullemans | 92926b8f30 | |
Gregory Trullemans | 977ff19ffd | |
Gregory Trullemans | a8019b6e8d |
|
@ -28,7 +28,7 @@ services:
|
|||
### Installation de weasyprint
|
||||
En plus du `pip install weasyprint` et `pip install django-weasyprint`, il faut installer weasyprint (via homebrew, …)
|
||||
puis, **pour les mac M1** exécuter les commandes :
|
||||
```
|
||||
```bash
|
||||
sudo ln -s /opt/homebrew/opt/glib/lib/libgobject-2.0.0.dylib /usr/local/lib/gobject-2.0
|
||||
sudo ln -s /opt/homebrew/opt/pango/lib/libpango-1.0.dylib /usr/local/lib/pango-1.0
|
||||
sudo ln -s /opt/homebrew/opt/harfbuzz/lib/libharfbuzz.dylib /usr/local/lib/harfbuzz
|
||||
|
@ -71,12 +71,12 @@ Pour transferer des données d'un site à un autre, le plus simple est d'utilise
|
|||
|
||||
Pour ne pas récupérer les user, les authorisation et les content-type, utilisez la commande :
|
||||
|
||||
```
|
||||
```bash
|
||||
python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > save.json
|
||||
```
|
||||
|
||||
Pour charger les données, tapez ensuite :
|
||||
```
|
||||
```bash
|
||||
python manage.py loaddata save.json
|
||||
```
|
||||
## Applications
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% load static %}
|
||||
{% load menuitems %}
|
||||
{% load submenuitems %}
|
||||
{% load has_group %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -75,8 +76,21 @@
|
|||
<ul class="nav">
|
||||
{% menuitem 'home' 'fal fa-chart-pie' 'Dashboard' %}
|
||||
{% menuitem 'gymnast_list' 'tim-icons icon-badge' 'Gymnasts' %}
|
||||
{% menuitem 'skill_list' 'tim-icons icon-molecule-40' 'Skills' %}
|
||||
{% menuitem 'routine_list' 'tim-icons icon-components' 'Routines' %}
|
||||
{% menuitem 'skill_list' 'fal fa-hexagon' 'Skills' %}
|
||||
<li>
|
||||
<a data-toggle="collapse" href="#pagesExamples">
|
||||
<i class="tim-icons icon-molecule-40"></i>
|
||||
<p>Combinations<b class="caret"></b></p>
|
||||
</a>
|
||||
<div class="collapse" id="pagesExamples">
|
||||
<ul class="nav">
|
||||
{% submenuitem 'competition_routine_listing' 'CR' 'Competition Routine' %}
|
||||
{% submenuitem 'routine_listing' 'R' 'Routine' %}
|
||||
{% submenuitem 'educative_combination_listing' 'E' 'Educative' %}
|
||||
{% submenuitem 'combination_list' 'C' 'Combination' %}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{% menuitem 'event_list' 'fal fa-calendar-alt' 'Events' %}
|
||||
{% if request.user|has_group:"trainer" %}
|
||||
{% menuitem 'accident_list' 'fal fa-comment-alt-medical' 'Accidents' %}
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.views.decorators.http import require_http_methods
|
|||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
|
||||
from jarvis.objective.models import Routine
|
||||
from jarvis.objective.models import Combination
|
||||
from jarvis.profiles.models import Profile
|
||||
from jarvis.followup.models import Skill, Point, Chrono
|
||||
from jarvis.location.models import Place, Club
|
||||
|
@ -120,7 +120,7 @@ def home(request):
|
|||
nb_active_gymnast = Gymnast.objects.filter(is_active=True).count()
|
||||
nb_event = Event.objects.all().count()
|
||||
nb_skill = Skill.objects.all().count()
|
||||
nb_routine = Routine.objects.all().count()
|
||||
nb_routine = Combination.objects.filter(is_routine=True).count()
|
||||
nb_score = Point.objects.all().count()
|
||||
nb_club = Club.objects.all().count()
|
||||
# percentage_week = int(
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# Generated by Django 4.2 on 2023-04-30 10:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("objective", "0017_combination_combinationskill_and_more"),
|
||||
("followup", "0044_alter_seasoninformation_number_of_hours_per_week_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="gymnasthasroutine",
|
||||
name="routine",
|
||||
field=models.ForeignKey(
|
||||
limit_choices_to={"is_routine": True},
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="done_by_gymnast",
|
||||
to="objective.combination",
|
||||
verbose_name="Routine",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="numberofroutinedone",
|
||||
name="routine",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
limit_choices_to={"is_routine": True},
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="number_of_try",
|
||||
to="objective.combination",
|
||||
verbose_name="Routine",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -6,7 +6,7 @@ from datetime import date
|
|||
from jarvis.tools.models import Markdownizable, Seasonisable
|
||||
from jarvis.people.models import Gymnast, GENDER_CHOICES
|
||||
from jarvis.planning.models import Event
|
||||
from jarvis.objective.models import Educative, Skill, Routine
|
||||
from jarvis.objective.models import Educative, Skill, Combination
|
||||
from jarvis.location.models import Club
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -311,9 +311,10 @@ class GymnastHasRoutine(models.Model):
|
|||
on_delete=models.CASCADE,
|
||||
)
|
||||
routine = models.ForeignKey(
|
||||
Routine,
|
||||
Combination,
|
||||
verbose_name="Routine",
|
||||
related_name="done_by_gymnast",
|
||||
limit_choices_to={"is_routine": True},
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
routine_type = models.PositiveSmallIntegerField(
|
||||
|
@ -343,10 +344,11 @@ class NumberOfRoutineDone(Seasonisable):
|
|||
on_delete=models.CASCADE,
|
||||
)
|
||||
routine = models.ForeignKey(
|
||||
Routine,
|
||||
Combination,
|
||||
verbose_name="Routine",
|
||||
related_name="number_of_try",
|
||||
on_delete=models.SET_NULL,
|
||||
limit_choices_to={"is_routine": True},
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
|
|
@ -11,8 +11,8 @@ from django_admin_listfilter_dropdown.filters import (
|
|||
from .models import (
|
||||
TouchPosition,
|
||||
Skill,
|
||||
Routine,
|
||||
RoutineSkill,
|
||||
Combination,
|
||||
CombinationSkill,
|
||||
PrerequisiteClosure,
|
||||
)
|
||||
|
||||
|
@ -98,8 +98,8 @@ class SkillAdmin(admin.ModelAdmin):
|
|||
)
|
||||
|
||||
|
||||
class RoutineAdmin(admin.ModelAdmin):
|
||||
model = Routine
|
||||
class CombinationAdmin(admin.ModelAdmin):
|
||||
model = Combination
|
||||
|
||||
fields = (
|
||||
"long_label",
|
||||
|
@ -119,10 +119,12 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
"age_girl_masterised",
|
||||
"is_active",
|
||||
"is_competitive",
|
||||
"is_routine",
|
||||
)
|
||||
list_display = (
|
||||
"long_label",
|
||||
"short_label",
|
||||
"is_routine",
|
||||
"is_competitive",
|
||||
"is_active",
|
||||
"level",
|
||||
|
@ -145,7 +147,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
class Media:
|
||||
js = (
|
||||
"js/core/jquery-3.6.0.min.js",
|
||||
"js/admin/routine.js",
|
||||
"js/admin/combination.js",
|
||||
)
|
||||
|
||||
# TODO: ne proposer QUE les SKILL comme educatif
|
||||
|
@ -155,19 +157,19 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
# return super(Skill, self).get_related_filter(model, request)
|
||||
|
||||
|
||||
class RoutineSkillAdmin(admin.ModelAdmin):
|
||||
model = RoutineSkill
|
||||
class CombinationSkillAdmin(admin.ModelAdmin):
|
||||
model = CombinationSkill
|
||||
|
||||
list_display = ("routine", "skill", "rank")
|
||||
list_display = ("combination", "skill", "rank")
|
||||
list_filter = (("rank", DropdownFilter),)
|
||||
search_fields = (
|
||||
"routine__long_label",
|
||||
"routine__short_label",
|
||||
"combination__long_label",
|
||||
"combination__short_label",
|
||||
"skill__long_label",
|
||||
"skill__short_label",
|
||||
)
|
||||
ordering = ("routine",)
|
||||
autocomplete_fields = ("routine", "skill")
|
||||
ordering = ("combination",)
|
||||
autocomplete_fields = ("combination", "skill")
|
||||
|
||||
|
||||
class PrerequisiteClosureAdmin(admin.ModelAdmin):
|
||||
|
@ -188,6 +190,6 @@ class PrerequisiteClosureAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(TouchPosition, TouchPositionAdmin)
|
||||
admin.site.register(Skill, SkillAdmin)
|
||||
admin.site.register(Routine, RoutineAdmin)
|
||||
admin.site.register(RoutineSkill, RoutineSkillAdmin)
|
||||
admin.site.register(Combination, CombinationAdmin)
|
||||
admin.site.register(CombinationSkill, CombinationSkillAdmin)
|
||||
admin.site.register(PrerequisiteClosure, PrerequisiteClosureAdmin)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django import forms
|
||||
|
||||
from .models import Skill, Routine, RoutineSkill
|
||||
from .models import Skill, Combination, CombinationSkill
|
||||
|
||||
|
||||
class SkillForm(forms.ModelForm):
|
||||
|
@ -17,9 +17,9 @@ class SkillForm(forms.ModelForm):
|
|||
}
|
||||
|
||||
|
||||
class RoutineForm(forms.ModelForm):
|
||||
class CombinationForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Routine
|
||||
model = Combination
|
||||
fields = (
|
||||
"long_label",
|
||||
"short_label",
|
||||
|
@ -30,10 +30,16 @@ class RoutineForm(forms.ModelForm):
|
|||
)
|
||||
widgets = {
|
||||
"long_label": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Routine's long name"}
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Combination's long name",
|
||||
}
|
||||
),
|
||||
"short_label": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Routine's short name"}
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Combination's short name",
|
||||
}
|
||||
),
|
||||
"informations": forms.Textarea(
|
||||
attrs={
|
||||
|
@ -47,16 +53,16 @@ class RoutineForm(forms.ModelForm):
|
|||
}
|
||||
|
||||
|
||||
class RoutineSkillForm(forms.ModelForm):
|
||||
class CombinationSkillForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = RoutineSkill
|
||||
model = CombinationSkill
|
||||
fields = (
|
||||
"routine",
|
||||
"combination",
|
||||
"skill",
|
||||
"rank",
|
||||
)
|
||||
widgets = {
|
||||
"routine": forms.HiddenInput(),
|
||||
"combination": forms.HiddenInput(),
|
||||
"skill": forms.HiddenInput(),
|
||||
"rank": forms.NumberInput(),
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.2 on 2023-04-29 15:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("objective", "0015_alter_skill_position"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="routine",
|
||||
name="is_routine",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
# Generated by Django 4.2 on 2023-04-30 10:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("objective", "0016_routine_is_routine"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel("Routine", "Combination"),
|
||||
migrations.RenameModel("RoutineSkill", "CombinationSkill"),
|
||||
]
|
|
@ -1,5 +1,5 @@
|
|||
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
|
||||
|
||||
|
@ -244,20 +244,22 @@ class Skill(Educative):
|
|||
return f"{self.long_label} ({self.notation})"
|
||||
|
||||
|
||||
class Routine(Educative):
|
||||
class Combination(Educative):
|
||||
"""
|
||||
Classe représentant une série (enchainement de plusieurs figures). Elle hérite de la classe
|
||||
Classe représentant une série (c-à-d. un enchainement de plusieurs figures). Elle hérite de la classe
|
||||
`Educative`.
|
||||
TODO: il faudrait changer le nom de la classe en "Combination".
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Routine"
|
||||
verbose_name_plural = "Routines"
|
||||
verbose_name = "Combination"
|
||||
verbose_name_plural = "Combinations"
|
||||
|
||||
jumps = models.ManyToManyField(
|
||||
Skill, through="RoutineSkill", verbose_name="routine"
|
||||
Skill, through="CombinationSkill", verbose_name="combination"
|
||||
)
|
||||
is_active = models.BooleanField(default=True)
|
||||
is_routine = models.BooleanField(default=False)
|
||||
is_competitive = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -267,15 +269,15 @@ class Routine(Educative):
|
|||
"""Calcule les informations (rank, niveau, ages, …) d'une routine."""
|
||||
rank = 0
|
||||
level = 0
|
||||
age_boy_with_help = 0
|
||||
age_girl_with_help = 0
|
||||
age_boy_without_help = 0
|
||||
age_girl_without_help = 0
|
||||
difficulty = 0
|
||||
age_boy_chained = 0
|
||||
age_girl_chained = 0
|
||||
age_boy_with_help = 0
|
||||
age_girl_with_help = 0
|
||||
age_boy_masterised = 0
|
||||
age_girl_masterised = 0
|
||||
difficulty = 0
|
||||
age_boy_without_help = 0
|
||||
age_girl_without_help = 0
|
||||
is_competitive = True
|
||||
|
||||
for skill_link in self.skill_links.all():
|
||||
|
@ -392,21 +394,27 @@ class Routine(Educative):
|
|||
).exists()
|
||||
|
||||
|
||||
class RoutineSkill(models.Model):
|
||||
class CombinationSkill(models.Model):
|
||||
"""
|
||||
Classe de liaison permettant de liée une figure à une série. (relation n-n)
|
||||
TODO: devrait être renommée en "CombinationSkill".
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
ordering = ("rank",)
|
||||
|
||||
routine = models.ForeignKey(
|
||||
Routine, on_delete=models.CASCADE, default=None, related_name="skill_links"
|
||||
combination = models.ForeignKey(
|
||||
Combination,
|
||||
on_delete=models.CASCADE,
|
||||
default=None,
|
||||
related_name="skill_links",
|
||||
)
|
||||
skill = models.ForeignKey(
|
||||
Skill, on_delete=models.CASCADE, default=None, related_name="routine_links"
|
||||
Skill, on_delete=models.CASCADE, default=None, related_name="combination_links"
|
||||
)
|
||||
rank = models.PositiveSmallIntegerField()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.rank} - {self.routine.short_label} : {self.skill.short_label}"
|
||||
return (
|
||||
f"{self.rank} - {self.combination.short_label} : {self.skill.short_label}"
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<h4 class=""> Routines' Listing {% if gymnast_id %}for <i>{{ gymnast }}</i>{% endif %}</h4>
|
||||
<h4 class=""> {{ title }} Listing {% if gymnast_id %}for <i>{{ gymnast }}</i>{% endif %}</h4>
|
||||
</div>
|
||||
<div class="col-1 ml-auto">
|
||||
<div class="text-right">
|
|
@ -12,39 +12,57 @@ urlpatterns = [
|
|||
path(r"skill/search/", views.skill_listing, name="skill_search"),
|
||||
path(r"skill/<int:skill_id>/", views.skill_details, name="skill_details"),
|
||||
path(
|
||||
r"skill/<int:skill_id>/edit/",
|
||||
views.skill_create_or_update,
|
||||
name="skill_update"
|
||||
r"skill/<int:skill_id>/edit/", views.skill_create_or_update, name="skill_update"
|
||||
),
|
||||
path(r"skill/<int:skill_id>/tree/", views.skill_tree, name="skill_tree"),
|
||||
path(
|
||||
r"skill/prerequisiteless/",
|
||||
views.skill_without_prerequisite_listing,
|
||||
name="skill_without_prerequisite"
|
||||
name="skill_without_prerequisite",
|
||||
),
|
||||
path(r"skill/", views.skill_listing, name="skill_list"),
|
||||
|
||||
# Routines
|
||||
path(r"routine/lookup/", views.routine_lookup, name="routine_lookup"),
|
||||
path(r"routine/search/", views.routine_listing, name="routine_search"),
|
||||
path(r"routine/add/", views.routine_create_or_update, name="routine_create"),
|
||||
path(r"combination/lookup/", views.routine_lookup, name="routine_lookup"),
|
||||
path(r"combination/search/", views.routine_listing, name="routine_search"),
|
||||
path(r"combination/add/", views.routine_create_or_update, name="routine_create"),
|
||||
path(
|
||||
r"routine/edit/<int:routine_id>/",
|
||||
r"combination/edit/<int:routine_id>/",
|
||||
views.routine_create_or_update,
|
||||
name="routine_update"
|
||||
name="routine_update",
|
||||
),
|
||||
path(r"routine/<int:routine_id>/", views.routine_details, name="routine_details"),
|
||||
path(r"routine/compose/<int:routine_id>/", views.compose_routine, name="compose_routine"),
|
||||
path(
|
||||
r"routine/compose/link_skill/",
|
||||
r"combination/<int:routine_id>/", views.routine_details, name="routine_details"
|
||||
),
|
||||
path(
|
||||
r"combination/compose/<int:routine_id>/",
|
||||
views.compose_routine,
|
||||
name="compose_routine",
|
||||
),
|
||||
path(
|
||||
r"combination/compose/link_skill/",
|
||||
views.link_skill_to_routine,
|
||||
name="link_skill_to_routine",
|
||||
),
|
||||
path(
|
||||
r"routine/compose/unlink_skill/",
|
||||
r"combination/compose/unlink_skill/",
|
||||
views.unlink_skill_from_routine,
|
||||
name="unlink_skill_from_routine",
|
||||
),
|
||||
path(r"routine/", views.routine_listing, name="routine_list"),
|
||||
path(r"routine/gymnast/<int:gymnast_id>/", views.routine_listing, name="routine_list_for_gymnast"),
|
||||
path(
|
||||
r"combination/gymnast/<int:gymnast_id>/",
|
||||
views.routine_listing,
|
||||
name="routine_list_for_gymnast",
|
||||
),
|
||||
path(r"combination/", views.combination_listing, name="combination_list"),
|
||||
path(
|
||||
r"combination/educative/",
|
||||
views.educative_combination_listing,
|
||||
name="educative_combination_listing",
|
||||
),
|
||||
path(r"combination/routine/", views.routine_listing, name="routine_listing"),
|
||||
path(
|
||||
r"combination/competition_routine/",
|
||||
views.competition_routine_listing,
|
||||
name="competition_routine_listing",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,13 +9,13 @@ from jarvis.people.models import Gymnast
|
|||
|
||||
from .forms import (
|
||||
SkillForm,
|
||||
RoutineForm,
|
||||
RoutineSkillForm,
|
||||
CombinationForm,
|
||||
CombinationSkillForm,
|
||||
)
|
||||
from .models import (
|
||||
Skill,
|
||||
Routine,
|
||||
RoutineSkill,
|
||||
Combination,
|
||||
CombinationSkill,
|
||||
PrerequisiteClosure,
|
||||
)
|
||||
|
||||
|
@ -174,6 +174,37 @@ def skill_create_or_update(request, skill_id=None):
|
|||
return render(request, "skills/create.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def competition_routine_listing(request, gymnast_id=None):
|
||||
"""Récupère la liste des routines suivant un pattern si celui-ci est défini"""
|
||||
|
||||
gymnast = None
|
||||
pattern = request.GET.get("pattern", None)
|
||||
if pattern:
|
||||
routine_list = Combination.objects.filter(
|
||||
is_routine=True, is_competitive=True
|
||||
).filter(Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern))
|
||||
else:
|
||||
if gymnast_id:
|
||||
routine_list = Combination.objects.filter(
|
||||
is_routine=True, is_competitive=True
|
||||
).filter(done_by_gymnast__gymnast=gymnast_id)
|
||||
gymnast = Gymnast.objects.get(pk=gymnast_id)
|
||||
else:
|
||||
routine_list = Combination.objects.filter(
|
||||
is_routine=True, is_competitive=True
|
||||
)
|
||||
|
||||
context = {
|
||||
"title": "Competition Routines",
|
||||
"routine_list": routine_list,
|
||||
"gymnast_id": gymnast_id,
|
||||
"gymnast": gymnast,
|
||||
}
|
||||
return render(request, "combinations/list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def routine_listing(request, gymnast_id=None):
|
||||
|
@ -182,22 +213,83 @@ def routine_listing(request, gymnast_id=None):
|
|||
gymnast = None
|
||||
pattern = request.GET.get("pattern", None)
|
||||
if pattern:
|
||||
routine_list = Routine.objects.filter(
|
||||
routine_list = Combination.objects.filter(is_routine=True).filter(
|
||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||
)
|
||||
else:
|
||||
if gymnast_id:
|
||||
routine_list = Routine.objects.filter(done_by_gymnast__gymnast=gymnast_id)
|
||||
routine_list = Combination.objects.filter(is_routine=True).filter(
|
||||
done_by_gymnast__gymnast=gymnast_id
|
||||
)
|
||||
gymnast = Gymnast.objects.get(pk=gymnast_id)
|
||||
else:
|
||||
routine_list = Routine.objects.all()
|
||||
routine_list = Combination.objects.filter(is_routine=True)
|
||||
|
||||
context = {
|
||||
"title": "Routines",
|
||||
"routine_list": routine_list,
|
||||
"gymnast_id": gymnast_id,
|
||||
"gymnast": gymnast,
|
||||
}
|
||||
return render(request, "routines/list.html", context)
|
||||
return render(request, "combinations/list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def educative_combination_listing(request, gymnast_id=None):
|
||||
"""Récupère la liste des routines suivant un pattern si celui-ci est défini"""
|
||||
|
||||
gymnast = None
|
||||
pattern = request.GET.get("pattern", None)
|
||||
if pattern:
|
||||
routine_list = Combination.objects.filter(is_routine=False).filter(
|
||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||
)
|
||||
else:
|
||||
if gymnast_id:
|
||||
routine_list = Combination.objects.filter(is_routine=False).filter(
|
||||
done_by_gymnast__gymnast=gymnast_id
|
||||
)
|
||||
gymnast = Gymnast.objects.get(pk=gymnast_id)
|
||||
else:
|
||||
routine_list = Combination.objects.filter(is_routine=False)
|
||||
|
||||
context = {
|
||||
"title": "Educative",
|
||||
"routine_list": routine_list,
|
||||
"gymnast_id": gymnast_id,
|
||||
"gymnast": gymnast,
|
||||
}
|
||||
return render(request, "combinations/list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def combination_listing(request, gymnast_id=None):
|
||||
"""Récupère la liste des routines suivant un pattern si celui-ci est défini"""
|
||||
|
||||
gymnast = None
|
||||
pattern = request.GET.get("pattern", None)
|
||||
if pattern:
|
||||
routine_list = Combination.objects.filter(
|
||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||
)
|
||||
else:
|
||||
if gymnast_id:
|
||||
routine_list = Combination.objects.filter(
|
||||
done_by_gymnast__gymnast=gymnast_id
|
||||
)
|
||||
gymnast = Gymnast.objects.get(pk=gymnast_id)
|
||||
else:
|
||||
routine_list = Combination.objects.all()
|
||||
|
||||
context = {
|
||||
"title": "Combinations",
|
||||
"routine_list": routine_list,
|
||||
"gymnast_id": gymnast_id,
|
||||
"gymnast": gymnast,
|
||||
}
|
||||
return render(request, "combinations/list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -209,8 +301,12 @@ def routine_lookup(request):
|
|||
pattern = request.POST.get("pattern", None)
|
||||
|
||||
if pattern is not None and len(pattern) >= 3:
|
||||
results = Routine.objects.filter(
|
||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||
results = (
|
||||
Combination()
|
||||
.objects.filter(is_routine=True)
|
||||
.filter(
|
||||
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||
)
|
||||
)
|
||||
place_list = [{"id": x.id, "label": str(x)} for x in results]
|
||||
|
||||
|
@ -226,42 +322,44 @@ def routine_details(request, routine_id):
|
|||
routine_id int identifiant d'une routine
|
||||
"""
|
||||
|
||||
routine = get_object_or_404(Routine, pk=routine_id)
|
||||
routine = get_object_or_404(Combination, pk=routine_id)
|
||||
routine.compute_informations()
|
||||
context = {"routine": routine, "skill_link_list": routine.skill_links.all()}
|
||||
return render(request, "routines/details.html", context)
|
||||
return render(request, "combinations/details.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def routine_create_or_update(request, routine_id=None):
|
||||
def routine_create_or_update(request, combination_id=None):
|
||||
"""Création d'une série.
|
||||
|
||||
Args:
|
||||
routine_id (int): identifiant d'un object de classe <routine>.
|
||||
combination_id (int): identifiant d'un object de classe <routine>.
|
||||
"""
|
||||
|
||||
if routine_id:
|
||||
routine = get_object_or_404(Routine, pk=routine_id)
|
||||
if combination_id:
|
||||
combination = get_object_or_404(Combination, pk=combination_id)
|
||||
else:
|
||||
routine = None
|
||||
combination = None
|
||||
|
||||
if request.method == "POST":
|
||||
form = RoutineForm(request.POST, instance=routine)
|
||||
form = CombinationForm(request.POST, instance=combination)
|
||||
|
||||
if form.is_valid():
|
||||
routine = form.save()
|
||||
combination = form.save()
|
||||
# ici faire un FOR skill in form_skills_list:
|
||||
# record.save() # ca sauve le record dans la table RoutineSkill
|
||||
# something like this : http://stackoverflow.com/questions/3074938/django-m2m-form-save-through-table
|
||||
# TO_FRED : can you help me ?
|
||||
return HttpResponseRedirect(reverse("routine_details", args=(routine.pk,)))
|
||||
return HttpResponseRedirect(
|
||||
reverse("routine_details", args=(combination.pk,))
|
||||
)
|
||||
else:
|
||||
return render(request, "routines/create.html", {"form": form})
|
||||
return render(request, "combinations/create.html", {"form": form})
|
||||
|
||||
form = RoutineForm(instance=routine)
|
||||
context = {"form": form, "routine_id": routine_id}
|
||||
return render(request, "routines/create.html", context)
|
||||
form = CombinationForm(instance=combination)
|
||||
context = {"form": form, "routine_id": combination_id}
|
||||
return render(request, "combinations/create.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -271,7 +369,7 @@ def compose_routine(request, routine_id):
|
|||
Récupère une routine et les sauts associés.
|
||||
"""
|
||||
|
||||
routine = get_object_or_404(Routine, pk=routine_id)
|
||||
routine = get_object_or_404(Combination, pk=routine_id)
|
||||
skill_link_list = routine.skill_links.all()
|
||||
skill_list = Skill.objects.all()
|
||||
context = {
|
||||
|
@ -280,7 +378,7 @@ def compose_routine(request, routine_id):
|
|||
"number_of_skill": skill_link_list.count(),
|
||||
"skill_list": skill_list,
|
||||
}
|
||||
return render(request, "routines/compose.html", context)
|
||||
return render(request, "combinations/compose.html", context)
|
||||
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
|
@ -289,14 +387,14 @@ def link_skill_to_routine(request):
|
|||
Recoit trois informations permettant de lier complètement un saut à une routine
|
||||
"""
|
||||
data = {
|
||||
"routine": get_object_or_404(Routine, pk=request.POST.get("routine_id", 0)),
|
||||
"routine": get_object_or_404(Combination, pk=request.POST.get("routine_id", 0)),
|
||||
"skill": get_object_or_404(Skill, pk=request.POST.get("skill_id", 0)),
|
||||
"rank": request.POST.get("rank", 0),
|
||||
}
|
||||
form = RoutineSkillForm(data)
|
||||
form = CombinationSkillForm(data)
|
||||
|
||||
if form.is_valid():
|
||||
link, created = RoutineSkill.objects.get_or_create(
|
||||
link, created = CombinationSkill.objects.get_or_create(
|
||||
routine=form.cleaned_data["routine"],
|
||||
skill=form.cleaned_data["skill"],
|
||||
rank=form.cleaned_data["rank"],
|
||||
|
@ -313,9 +411,9 @@ def unlink_skill_from_routine(request):
|
|||
"""
|
||||
order = request.POST.get("order", None)
|
||||
routine_id = request.POST.get("routine_id", None)
|
||||
routine = get_object_or_404(Routine, pk=routine_id)
|
||||
routine = get_object_or_404(Combination, pk=routine_id)
|
||||
try:
|
||||
RoutineSkill.objects.get(routine=routine, rank=order).delete()
|
||||
CombinationSkill.objects.get(routine=routine, rank=order).delete()
|
||||
except Exception:
|
||||
return HttpResponse(409)
|
||||
|
||||
|
|
|
@ -33,8 +33,9 @@ def menuitem(context, url, css_class, title):
|
|||
css_class,
|
||||
title,
|
||||
)
|
||||
|
||||
if context.request.path == url: # si le contexte est "/"
|
||||
# QTF : est ce que ca ne pourrait pas être fusionner avec les ligne 15-21 ?
|
||||
# si le contexte est "/"
|
||||
if context.request.path == url:
|
||||
return format_html(
|
||||
'<li class="active"><a href="{}"><i class="{}"></i><p>{}</p></a></li>',
|
||||
url,
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
from django import template
|
||||
from django.utils.html import format_html
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def submenuitem(context, url, minititle, title):
|
||||
url = reverse(url)
|
||||
# css_class = "" + css_class
|
||||
|
||||
return format_html(
|
||||
'<li><a href="{}"><span class="sidebar-mini-icon">{}</span><span class="sidebar-normal">{}</span></a></li>',
|
||||
url,
|
||||
minititle,
|
||||
title,
|
||||
)
|
Loading…
Reference in New Issue