[WIP] Road to combination feature
This commit is contained in:
parent
982f44b38b
commit
a0fd0faa57
|
@ -28,7 +28,7 @@ services:
|
||||||
### Installation de weasyprint
|
### Installation de weasyprint
|
||||||
En plus du `pip install weasyprint` et `pip install django-weasyprint`, il faut installer weasyprint (via homebrew, …)
|
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 :
|
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/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/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
|
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 :
|
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
|
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 :
|
Pour charger les données, tapez ensuite :
|
||||||
```
|
```bash
|
||||||
python manage.py loaddata save.json
|
python manage.py loaddata save.json
|
||||||
```
|
```
|
||||||
## Applications
|
## Applications
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load menuitems %}
|
{% load menuitems %}
|
||||||
|
{% load submenuitems %}
|
||||||
{% load has_group %}
|
{% load has_group %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
@ -75,8 +76,21 @@
|
||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
{% menuitem 'home' 'fal fa-chart-pie' 'Dashboard' %}
|
{% menuitem 'home' 'fal fa-chart-pie' 'Dashboard' %}
|
||||||
{% menuitem 'gymnast_list' 'tim-icons icon-badge' 'Gymnasts' %}
|
{% menuitem 'gymnast_list' 'tim-icons icon-badge' 'Gymnasts' %}
|
||||||
{% menuitem 'skill_list' 'tim-icons icon-molecule-40' 'Skills' %}
|
{% menuitem 'skill_list' 'fal fa-hexagon' 'Skills' %}
|
||||||
{% menuitem 'routine_list' 'tim-icons icon-components' 'Routines' %}
|
<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' %}
|
{% menuitem 'event_list' 'fal fa-calendar-alt' 'Events' %}
|
||||||
{% if request.user|has_group:"trainer" %}
|
{% if request.user|has_group:"trainer" %}
|
||||||
{% menuitem 'accident_list' 'fal fa-comment-alt-medical' 'Accidents' %}
|
{% menuitem 'accident_list' 'fal fa-comment-alt-medical' 'Accidents' %}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
<td class="text-center">{{ routine_done.get_routine_type_display }}</td>
|
<td class="text-center">{{ routine_done.get_routine_type_display }}</td>
|
||||||
<td class="text-left">
|
<td class="text-left">
|
||||||
{% if routine_done.routine %}
|
{% if routine_done.routine %}
|
||||||
<a href="{% url 'routine_details' routine_done.routine.id %}">{{ routine_done.routine.long_label }}</a>
|
<a href="{% url 'combination_details' routine_done.routine.id %}">{{ routine_done.routine.long_label }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
-
|
-
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -118,12 +118,14 @@ class RoutineAdmin(admin.ModelAdmin):
|
||||||
"age_girl_chained",
|
"age_girl_chained",
|
||||||
"age_girl_masterised",
|
"age_girl_masterised",
|
||||||
"is_active",
|
"is_active",
|
||||||
|
"is_routine",
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
)
|
)
|
||||||
list_display = (
|
list_display = (
|
||||||
"long_label",
|
"long_label",
|
||||||
"short_label",
|
"short_label",
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
|
"is_routine",
|
||||||
"is_active",
|
"is_active",
|
||||||
"level",
|
"level",
|
||||||
"rank",
|
"rank",
|
||||||
|
@ -131,8 +133,9 @@ class RoutineAdmin(admin.ModelAdmin):
|
||||||
)
|
)
|
||||||
list_filter = (
|
list_filter = (
|
||||||
("level", DropdownFilter),
|
("level", DropdownFilter),
|
||||||
"difficulty",
|
("difficulty", DropdownFilter),
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
|
"is_routine",
|
||||||
"is_active",
|
"is_active",
|
||||||
)
|
)
|
||||||
search_fields = (
|
search_fields = (
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.2 on 2023-05-01 07:33
|
||||||
|
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
]
|
|
@ -258,6 +258,7 @@ class Routine(Educative):
|
||||||
Skill, through="RoutineSkill", verbose_name="routine"
|
Skill, through="RoutineSkill", verbose_name="routine"
|
||||||
)
|
)
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
|
is_routine = models.BooleanField(default=False)
|
||||||
is_competitive = models.BooleanField(default=False)
|
is_competitive = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<ol>
|
<ol>
|
||||||
{% for link in skill_link_list %}
|
{% for link in skill_link_list %}
|
||||||
<li>
|
<li>
|
||||||
<div class="form-group row pb-0 mb-0">
|
<div class="form-group row pb-0 mb-0">
|
||||||
<label class="col-1 col-sm-1 col-md-1 col-lg-1 col-xl-1 col-form-label pt-2 pb-0 text-right"> </label>
|
<label class="col-1 col-sm-1 col-md-1 col-lg-1 col-xl-1 col-form-label pt-2 pb-0 text-right"> </label>
|
||||||
<div class="col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11 pt-2 text-danger">
|
<div class="col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11 pt-2 text-danger">
|
||||||
{{ link.skill.notation }}
|
{{ link.skill.notation }}
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li>
|
<li>
|
||||||
<div class="form-group row pb-0 mb-0">
|
<div class="form-group row pb-0 mb-0">
|
||||||
<label class="col-1 col-sm-1 col-md-1 col-lg-1 col-xl-1 col-form-label text-right mb-0"> </label>
|
<label class="col-1 col-sm-1 col-md-1 col-lg-1 col-xl-1 col-form-label text-right mb-0"> </label>
|
||||||
<div class="col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11 mb-0">
|
<div class="col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11 mb-0">
|
||||||
<input type="text" name="skill" placeholder="Skill" class="form-control selectpicker" id="id_skill">
|
<input type="text" name="skill" placeholder="Skill" class="form-control selectpicker" id="id_skill">
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer pt-0">
|
<div class="card-footer pt-0">
|
||||||
<a href="{% url 'routine_details' routine.id %}">
|
<a href="{% url 'combination_details' routine.id %}">
|
||||||
<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>
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
select: function (event, ui) {
|
select: function (event, ui) {
|
||||||
number_of_skill += 1;
|
number_of_skill += 1;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "{% url 'link_skill_to_routine' %}",
|
url: "{% url 'link_skill_to_combination' %}",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
routine_id: {{ routine.id }},
|
routine_id: {{ routine.id }},
|
|
@ -12,7 +12,7 @@
|
||||||
<h4 class="">{% if routine_id %}Edit{% else %}Add{% endif %} Routine</h4>
|
<h4 class="">{% if routine_id %}Edit{% else %}Add{% endif %} Routine</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form action="{% if routine_id %}{% url 'routine_update' routine_id %}{% else %}{% url 'routine_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
<form action="{% if routine_id %}{% url 'combination_update' routine_id %}{% else %}{% url 'combination_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% for hidden in form.hidden_fields %}
|
{% for hidden in form.hidden_fields %}
|
||||||
{{ hidden }}
|
{{ hidden }}
|
|
@ -59,12 +59,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6 text-right">
|
<div class="col-6 text-right">
|
||||||
{% if request.user|has_group:"trainer" %}
|
{% if request.user|has_group:"trainer" %}
|
||||||
<a href="{% url 'compose_routine' routine.id %}">
|
<a href="{% url 'compose_combination' routine.id %}">
|
||||||
<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-molecule-40"></i>
|
<i class="tim-icons icon-molecule-40"></i>
|
||||||
</button>
|
</button>
|
||||||
</a>
|
</a>
|
||||||
<a href="{% url 'routine_update' routine.id %}">
|
<a href="{% url 'combination_update' routine.id %}">
|
||||||
<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-pencil"></i>
|
<i class="tim-icons icon-pencil"></i>
|
||||||
</button>
|
</button>
|
|
@ -6,12 +6,12 @@
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-8">
|
<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>
|
||||||
<div class="col-1 ml-auto">
|
<div class="col-1 ml-auto">
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
{% if request.user|has_group:"trainer" %}
|
{% if request.user|has_group:"trainer" %}
|
||||||
<a href="{% url 'routine_create' %}">
|
<a href="{% url 'combination_create' %}">
|
||||||
<button type="submit" value="add" class="btn btn-icon btn-warning mb-0">
|
<button type="submit" value="add" class="btn btn-icon btn-warning mb-0">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -45,13 +45,13 @@
|
||||||
<tr role="row" class="{% cycle 'odd' 'even' %}">
|
<tr role="row" class="{% cycle 'odd' 'even' %}">
|
||||||
{% if request.user|has_group:"trainer" %}
|
{% if request.user|has_group:"trainer" %}
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'routine_update' routine.id %}">
|
<a href="{% url 'combination_update' routine.id %}">
|
||||||
<span class="tim-icons icon-pencil text-warning"></span>
|
<span class="tim-icons icon-pencil text-warning"></span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td class="text-left"><a href="{% url 'routine_details' routine.id %}">{{ routine.long_label }}</a></td>
|
<td class="text-left"><a href="{% url 'combination_details' routine.id %}">{{ routine.long_label }}</a></td>
|
||||||
<td class="text-left"><a href="{% url 'routine_details' routine.id %}">{{ routine.short_label }}</a></td>
|
<td class="text-left"><a href="{% url 'combination_details' routine.id %}">{{ routine.short_label }}</a></td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% if routine.is_competitive %}<i class="fa fa-check text-success" aria-hidden="true"></i>
|
{% if routine.is_competitive %}<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
{% else %}<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
{% else %}<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
|
@ -1,5 +1,5 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse, resolve
|
from django.urls import resolve
|
||||||
|
|
||||||
|
|
||||||
class URLTestCase(TestCase):
|
class URLTestCase(TestCase):
|
||||||
|
@ -27,28 +27,46 @@ class URLTestCase(TestCase):
|
||||||
|
|
||||||
def test_routine_url(self):
|
def test_routine_url(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/objective/routine/lookup/").view_name, "routine_lookup"
|
resolve("/objective/combination/lookup/").view_name, "routine_lookup"
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/objective/routine/search/").view_name, "routine_search"
|
resolve("/objective/combination/search/").view_name, "routine_search"
|
||||||
)
|
|
||||||
self.assertEqual(resolve("/objective/routine/add/").view_name, "routine_create")
|
|
||||||
self.assertEqual(
|
|
||||||
resolve("/objective/routine/edit/1/").view_name, "routine_update"
|
|
||||||
)
|
|
||||||
self.assertEqual(resolve("/objective/routine/1/").view_name, "routine_details")
|
|
||||||
self.assertEqual(
|
|
||||||
resolve("/objective/routine/compose/1/").view_name, "compose_routine"
|
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/objective/routine/compose/link_skill/").view_name,
|
resolve("/objective/combination/add/").view_name, "combination_create"
|
||||||
"link_skill_to_routine",
|
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/objective/routine/compose/unlink_skill/").view_name,
|
resolve("/objective/combination/edit/1/").view_name, "combination_update"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
resolve("/objective/combination/1/").view_name, "combination_details"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
resolve("/objective/combination/compose/1/").view_name,
|
||||||
|
"compose_combination",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
resolve("/objective/combination/compose/link_skill/").view_name,
|
||||||
|
"link_skill_to_combination",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
resolve("/objective/combination/compose/unlink_skill/").view_name,
|
||||||
"unlink_skill_from_routine",
|
"unlink_skill_from_routine",
|
||||||
)
|
)
|
||||||
self.assertEqual(resolve("/objective/routine/").view_name, "routine_list")
|
self.assertEqual(
|
||||||
|
resolve("/combination/competition_routine/").view_name,
|
||||||
|
"competition_routine_listing",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(resolve("/combination/routine/").view_name, "routine_listing")
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
resolve("/combination/educative/").view_name,
|
||||||
|
"educative_combination_listing",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(resolve("/combination/").view_name, "combination_list")
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resolve("/objective/routine/gymnast/1/").view_name,
|
resolve("/objective/routine/gymnast/1/").view_name,
|
||||||
"routine_list_for_gymnast",
|
"routine_list_for_gymnast",
|
||||||
|
|
|
@ -12,39 +12,63 @@ urlpatterns = [
|
||||||
path(r"skill/search/", views.skill_listing, name="skill_search"),
|
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>/", views.skill_details, name="skill_details"),
|
||||||
path(
|
path(
|
||||||
r"skill/<int:skill_id>/edit/",
|
r"skill/<int:skill_id>/edit/", views.skill_create_or_update, name="skill_update"
|
||||||
views.skill_create_or_update,
|
|
||||||
name="skill_update"
|
|
||||||
),
|
),
|
||||||
path(r"skill/<int:skill_id>/tree/", views.skill_tree, name="skill_tree"),
|
path(r"skill/<int:skill_id>/tree/", views.skill_tree, name="skill_tree"),
|
||||||
path(
|
path(
|
||||||
r"skill/prerequisiteless/",
|
r"skill/prerequisiteless/",
|
||||||
views.skill_without_prerequisite_listing,
|
views.skill_without_prerequisite_listing,
|
||||||
name="skill_without_prerequisite"
|
name="skill_without_prerequisite",
|
||||||
),
|
),
|
||||||
path(r"skill/", views.skill_listing, name="skill_list"),
|
path(r"skill/", views.skill_listing, name="skill_list"),
|
||||||
|
# Combination
|
||||||
# Routines
|
path(r"combination/lookup/", views.routine_lookup, name="routine_lookup"),
|
||||||
path(r"routine/lookup/", views.routine_lookup, name="routine_lookup"),
|
path(r"combination/search/", views.routine_listing, name="routine_search"),
|
||||||
path(r"routine/search/", views.routine_listing, name="routine_search"),
|
|
||||||
path(r"routine/add/", views.routine_create_or_update, name="routine_create"),
|
|
||||||
path(
|
path(
|
||||||
r"routine/edit/<int:routine_id>/",
|
r"combination/add/",
|
||||||
views.routine_create_or_update,
|
views.combination_create_or_update,
|
||||||
name="routine_update"
|
name="combination_create",
|
||||||
),
|
|
||||||
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/",
|
|
||||||
views.link_skill_to_routine,
|
|
||||||
name="link_skill_to_routine",
|
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
r"routine/compose/unlink_skill/",
|
r"combination/edit/<int:combination_id>/",
|
||||||
|
views.combination_create_or_update,
|
||||||
|
name="combination_update",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
r"combination/<int:combination_id>/",
|
||||||
|
views.combination_details,
|
||||||
|
name="combination_details",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
r"combination/compose/<int:combination_id>/",
|
||||||
|
views.compose_combination,
|
||||||
|
name="compose_combination",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
r"combination/compose/link_skill/",
|
||||||
|
views.link_skill_to_combination,
|
||||||
|
name="link_skill_to_combination",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
r"combination/compose/unlink_skill/",
|
||||||
views.unlink_skill_from_routine,
|
views.unlink_skill_from_routine,
|
||||||
name="unlink_skill_from_routine",
|
name="unlink_skill_from_routine",
|
||||||
),
|
),
|
||||||
path(r"routine/", views.routine_listing, name="routine_list"),
|
path(
|
||||||
path(r"routine/gymnast/<int:gymnast_id>/", views.routine_listing, name="routine_list_for_gymnast"),
|
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",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -174,11 +174,98 @@ def skill_create_or_update(request, skill_id=None):
|
||||||
return render(request, "skills/create.html", context)
|
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 = Routine.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 = Routine.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 = Routine.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
|
@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 suivant un pattern si celui-ci est défini"""
|
||||||
|
|
||||||
|
gymnast = None
|
||||||
|
pattern = request.GET.get("pattern", None)
|
||||||
|
if pattern:
|
||||||
|
routine_list = Routine.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(is_routine=True).filter(
|
||||||
|
done_by_gymnast__gymnast=gymnast_id
|
||||||
|
)
|
||||||
|
gymnast = Gymnast.objects.get(pk=gymnast_id)
|
||||||
|
else:
|
||||||
|
routine_list = Routine.objects.filter(is_routine=True)
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"title": "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 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 = Routine.objects.filter(is_routine=False).filter(
|
||||||
|
Q(long_label__icontains=pattern) | Q(short_label__icontains=pattern)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if gymnast_id:
|
||||||
|
routine_list = Routine.objects.filter(is_routine=False).filter(
|
||||||
|
done_by_gymnast__gymnast=gymnast_id
|
||||||
|
)
|
||||||
|
gymnast = Gymnast.objects.get(pk=gymnast_id)
|
||||||
|
else:
|
||||||
|
routine_list = Routine.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
|
gymnast = None
|
||||||
pattern = request.GET.get("pattern", None)
|
pattern = request.GET.get("pattern", None)
|
||||||
if pattern:
|
if pattern:
|
||||||
|
@ -193,11 +280,12 @@ def routine_listing(request, gymnast_id=None):
|
||||||
routine_list = Routine.objects.all()
|
routine_list = Routine.objects.all()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
|
"title": "Combinations",
|
||||||
"routine_list": routine_list,
|
"routine_list": routine_list,
|
||||||
"gymnast_id": gymnast_id,
|
"gymnast_id": gymnast_id,
|
||||||
"gymnast": gymnast,
|
"gymnast": gymnast,
|
||||||
}
|
}
|
||||||
return render(request, "routines/list.html", context)
|
return render(request, "combinations/list.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -218,31 +306,31 @@ def routine_lookup(request):
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def routine_details(request, routine_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 routine (série).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
routine_id int identifiant d'une routine
|
combination_id int identifiant d'une routine
|
||||||
"""
|
"""
|
||||||
|
|
||||||
routine = get_object_or_404(Routine, pk=routine_id)
|
routine = get_object_or_404(Routine, pk=combination_id)
|
||||||
routine.compute_informations()
|
routine.compute_informations()
|
||||||
context = {"routine": routine, "skill_link_list": routine.skill_links.all()}
|
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
|
@login_required
|
||||||
@require_http_methods(["GET", "POST"])
|
@require_http_methods(["GET", "POST"])
|
||||||
def routine_create_or_update(request, routine_id=None):
|
def combination_create_or_update(request, combination_id=None):
|
||||||
"""Création d'une série.
|
"""Création d'une série.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
routine_id (int): identifiant d'un object de classe <routine>.
|
combination_id <int> identifiant d'un object de classe <routine>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if routine_id:
|
if combination_id:
|
||||||
routine = get_object_or_404(Routine, pk=routine_id)
|
routine = get_object_or_404(Routine, pk=combination_id)
|
||||||
else:
|
else:
|
||||||
routine = None
|
routine = None
|
||||||
|
|
||||||
|
@ -254,24 +342,29 @@ def routine_create_or_update(request, routine_id=None):
|
||||||
# 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
|
||||||
# TO_FRED : can you help me ?
|
# QTF : can you help me ?
|
||||||
return HttpResponseRedirect(reverse("routine_details", args=(routine.pk,)))
|
return HttpResponseRedirect(
|
||||||
|
reverse("combination_details", args=(routine.pk,))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return render(request, "routines/create.html", {"form": form})
|
return render(request, "combinations/create.html", {"form": form})
|
||||||
|
|
||||||
form = RoutineForm(instance=routine)
|
form = RoutineForm(instance=routine)
|
||||||
context = {"form": form, "routine_id": routine_id}
|
context = {"form": form, "combination_id": combination_id}
|
||||||
return render(request, "routines/create.html", context)
|
return render(request, "combinations/create.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def compose_routine(request, routine_id):
|
def compose_combination(request, combination_id):
|
||||||
"""
|
"""
|
||||||
Récupère une routine et les sauts associés.
|
Récupère une routine et les sauts associés sur base d'un id passé en paramètre.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
combination_id <int> identifiant d'un object de classe <routine>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
routine = get_object_or_404(Routine, pk=routine_id)
|
routine = get_object_or_404(Routine, pk=combination_id)
|
||||||
skill_link_list = routine.skill_links.all()
|
skill_link_list = routine.skill_links.all()
|
||||||
skill_list = Skill.objects.all()
|
skill_list = Skill.objects.all()
|
||||||
context = {
|
context = {
|
||||||
|
@ -280,16 +373,19 @@ def compose_routine(request, routine_id):
|
||||||
"number_of_skill": skill_link_list.count(),
|
"number_of_skill": skill_link_list.count(),
|
||||||
"skill_list": skill_list,
|
"skill_list": skill_list,
|
||||||
}
|
}
|
||||||
return render(request, "routines/compose.html", context)
|
return render(request, "combinations/compose.html", context)
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def link_skill_to_routine(request):
|
def link_skill_to_combination(request):
|
||||||
"""
|
"""
|
||||||
Recoit trois informations permettant de lier complètement un saut à une routine
|
Recoit dans request trois informations permettant de lier complètement un saut à une routine :
|
||||||
|
- combination_id <int> identifiant d'un object de classe <routine>
|
||||||
|
- skill_id <int> identifiant d'un object de classe <skill>
|
||||||
|
- rank <int> numéro de place du skill dans la routine
|
||||||
"""
|
"""
|
||||||
data = {
|
data = {
|
||||||
"routine": get_object_or_404(Routine, pk=request.POST.get("routine_id", 0)),
|
"routine": get_object_or_404(Routine, pk=request.POST.get("combination_id", 0)),
|
||||||
"skill": get_object_or_404(Skill, pk=request.POST.get("skill_id", 0)),
|
"skill": get_object_or_404(Skill, pk=request.POST.get("skill_id", 0)),
|
||||||
"rank": request.POST.get("rank", 0),
|
"rank": request.POST.get("rank", 0),
|
||||||
}
|
}
|
||||||
|
@ -309,13 +405,15 @@ def link_skill_to_routine(request):
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def unlink_skill_from_routine(request):
|
def unlink_skill_from_routine(request):
|
||||||
"""
|
"""
|
||||||
Recoit deux informations (routine_id & order) 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
|
||||||
|
- combination_id <int> identifiant d'un object de classe <routine>
|
||||||
"""
|
"""
|
||||||
order = request.POST.get("order", None)
|
rank = request.POST.get("order", None)
|
||||||
routine_id = request.POST.get("routine_id", None)
|
combination_id = request.POST.get("combination_id", None)
|
||||||
routine = get_object_or_404(Routine, pk=routine_id)
|
combination = get_object_or_404(Routine, pk=combination_id)
|
||||||
try:
|
try:
|
||||||
RoutineSkill.objects.get(routine=routine, rank=order).delete()
|
RoutineSkill.objects.get(routine=combination, rank=rank).delete()
|
||||||
except Exception:
|
except Exception:
|
||||||
return HttpResponse(409)
|
return HttpResponse(409)
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
{% for ghr in ghr_list %}
|
{% for ghr in ghr_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">{{ ghr.get_routine_type_display }}</td>
|
<td class="text-center">{{ ghr.get_routine_type_display }}</td>
|
||||||
<td class="text-left"><a href="{% url 'routine_details' ghr.routine.id %}">{{ ghr.routine.short_label }}</a></td>
|
<td class="text-left"><a href="{% url 'combination_details' ghr.routine.id %}">{{ ghr.routine.short_label }}</a></td>
|
||||||
<td class="text-center">{{ ghr.date_begin | date:"d-m-Y"}}</td>
|
<td class="text-center">{{ ghr.date_begin | date:"d-m-Y"}}</td>
|
||||||
<!-- <td class="text-center">{% if ghr.date_end %}{{ ghr.date_end | date:"d F Y" }}{% else %}… to now.{% endif %}</td> -->
|
<!-- <td class="text-center">{% if ghr.date_end %}{{ ghr.date_end | date:"d F Y" }}{% else %}… to now.{% endif %}</td> -->
|
||||||
<td class="text-center"><b>{{ ghr.routine.difficulty }}</b></td>
|
<td class="text-center"><b>{{ ghr.routine.difficulty }}</b></td>
|
||||||
|
|
|
@ -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