Merge branch 'master' into propal/pep8-pylint
This commit is contained in:
commit
e944ecdb34
|
@ -1,7 +1,9 @@
|
|||
# Application `Planning`
|
||||
|
||||
## Saison
|
||||
|
||||
Une saison est déinie par :
|
||||
|
||||
- un id,
|
||||
- un label,
|
||||
- une date de début et
|
||||
|
@ -11,9 +13,12 @@ La date de début est très souvent le : 01/09/xxxx
|
|||
La date de fin est très souvent le : 31/08/xxxy
|
||||
Exemple : 1/9/2015 - 31/8/2016
|
||||
|
||||
NOTE: Le fait que la date de début soit **très souvent** le 01 septembre indique sans doute une date par défaut (modifiable) au niveau du modèle. Idem pour la date de fin.
|
||||
|
||||
NOTE: je ne comprends pas la méthode `week_number_from_begin`. Si cela fait référence à la date de début, alors il faut le mentionner dans le nom de la fonction.
|
||||
|
||||
## Course
|
||||
|
||||
Un cours est un ensemble d'entraînements (`training`) (récurrents ?) défini par :
|
||||
- une heure de début et une heure de fin,
|
||||
- une date de début et une date de fin (un cours est considéré comme donné hebdomadairement entre
|
||||
|
@ -24,16 +29,32 @@ Un cours est un ensemble d'entraînements (`training`) (récurrents ?) défini p
|
|||
|
||||
Réflexion : les cours devraient-ils être liés à une saison ?
|
||||
|
||||
NOTE: Je dirais que oui. D'un côté, tu n'aurais pas de possibilité de déduction entre un cours et le moment où il y a réellement lieu - de ce que je comprends, le *cours* correspond en fait à quelque chose qui est prévu selon une récurrence donnée - eg. "tous les mardis (deuxième jour de la semaine), entre 10h et 12h, avec Machin, Chose et Brol".
|
||||
La *saison* va juste indiquer la date de début et de fin des cours qui y sont liés.
|
||||
|
||||
Même s'il y a moyen de le représenter différement, je pense surtout que le concept de saison parle à beaucoup de monde.
|
||||
|
||||
NOTE: la réflexion va surtout être "est-ce qu'un cours est différent entre deux saison ?" A priori, oui, puisque Bidule peut devenir entraineur pour la saison 2020-2021.
|
||||
|
||||
L'avantage, c'est que Machin pourrait se connecter sur son profil et dire "ah ouais, cette année, je donne cours le jeudi et le samedi."
|
||||
|
||||
## Training
|
||||
|
||||
Un entraînement est une occurence d'un cours pendant lequel des gmnastes sont présents.
|
||||
|
||||
Un objet de cette classe lie donc :
|
||||
|
||||
- un cours,
|
||||
- gymnaste et
|
||||
- un cours,
|
||||
- des gymnastes présents et
|
||||
- une date.
|
||||
|
||||
NOTE: Techniquement, tu peux ici mettre une contrainte ou un avertissement si l'entrainement est situé à une date différente de ce que la saison devrait autoriser.
|
||||
|
||||
NOTE: dans la classe Training, il est question d'une `ForeignKey` vers Gymnast, mais ce devrait être un ManyToManyField.
|
||||
|
||||
NOTE: De la même manière, je reprendrais aussi l'heure de début et de fin. Entre ce qui est prévu (le cours) et la réalité (l'entraintement), il pourrait y avoir des différences.
|
||||
|
||||
Cela permettrait aussi de planifier les cours - dire en gros que, en début d'année, tu (l'appli) planifies les jours fériés, et *projette* les entrainements pour la saison, sur base de ce qui est prévu.
|
||||
|
||||
|
||||
## Round
|
||||
|
@ -41,6 +62,10 @@ Un objet de cette classe lie donc :
|
|||
Classe représentant les passages des élèves lors d'un entrainement.
|
||||
Chaque record représente un passage. Il est donc lié à un record de la classe `Training`.
|
||||
|
||||
NOTE: Est-ce qu'il est important de savoir qui est l'entraineur qui a donné une évaluation ?
|
||||
|
||||
NOTE: au niveau du round, il y a un ensemble d'informations chronologiques: `nb_of_realisations` (au pluriel...), `nb_of_success`, ... mais c'est incohérent avec le `round_number`, puisque je suppose qu'il pourrait faire un tour de A, puis B, puis revenir à A.
|
||||
Cette partie-ci me semble très complexe - sans oublier qu'il va falloir la remplir: si tes entraineurs chipotent sur une tablette ou sur un écran pour chaque action que réalise un gymnaste, ça va pas être sympa pour eux.
|
||||
|
||||
|
||||
## Group
|
||||
|
@ -48,6 +73,11 @@ Chaque record représente un passage. Il est donc lié à un record de la classe
|
|||
Classe représentant les groupes (Loisir, D1, D2, A, B, …).
|
||||
Un groupe appartient à un club.
|
||||
|
||||
NOTE: pourquoi garder un champ `active` ? Il y a un risque qu'un groupe soit désactivé ? Si oui, ne vaut-il pas mieux garder le moment où il l'a été ?
|
||||
|
||||
NOTE: est-ce que le champ `name` n'est pas un dictionnaire fini ? Loisir, D1, D2, ... ?
|
||||
|
||||
NOTE: est-ce que tu n'as pas une contrainte sur le nom, le club et la saison ?
|
||||
|
||||
|
||||
## Subgroup
|
||||
|
@ -59,28 +89,33 @@ Un sous-groupe appartient à un groupe (pour rappel, lui-même lié à un club).
|
|||
De cette manière, quand un gymnaste est mis dans un sous-groupe, en remontant via le groupe,
|
||||
nous pouvons connaître le(s) club(s) du gymnaste pour chaque saison.
|
||||
|
||||
|
||||
NOTE: re-question sur le `name`. A mon avis, si le nom du groupe est fini, tu peux te passer d'une des classes `Group` ou `Subgroup`, et cela simplifierait pas mal la gestion du club.
|
||||
|
||||
## Unavailability
|
||||
|
||||
Classe représentant les indisponibilités.
|
||||
|
||||
NOTE: avec la réflexion ci-dessous, cela pourrait ne plus être utile. Les *Courses* correspondent à la modélisation tandis que les entrainements représentent le planifié/réalisé. Du coup, il suffit qu'un entrainenemnts n'existe pas pour qu'il ne soit pas planifié.
|
||||
|
||||
|
||||
## PlanningLine
|
||||
|
||||
Classe représentant les passages prévisionnels (incubating idea).
|
||||
|
||||
NOTE: en gros, tu veux proposer un entrainement personnalisé pour chaque gymnaste ;) Je ne vois pas la valeur ajoutée. Le mieux serait d'avoir une forme de proposition au niveau des Rounds et des Trainings, quitte à la modifier pendant l'entrainement. Sinon, je ne vois pas trop l'idée.
|
||||
|
||||
|
||||
## EventType
|
||||
|
||||
Classe représentant les types d'évènements.
|
||||
|
||||
C'est un dictionnaire fini :
|
||||
- compétiton qualificative,
|
||||
- compétition finale,
|
||||
- démonstration,
|
||||
- …
|
||||
|
||||
NOTE: tu peux utiliser un champ de type Choice, si le dictionnaire est fini. Cela te fera gagner une jointure. Si le dictionnaire a ***une*** chance d'avoir une nouvelle valeur, garde la table.
|
||||
|
||||
|
||||
## Event
|
||||
|
@ -95,6 +130,8 @@ Un évènement est caractérisé par :
|
|||
|
||||
Je ne me rapelle plus à quoi sert le club.
|
||||
|
||||
|
||||
NOTE: alors, retire le club :-p
|
||||
|
||||
## Event_Participation
|
||||
|
||||
NOTE: Dans Event, tu as déjà un lien avec des gymnastes, que tu reprends dans la classe EventParticipation (pas de "*_*"). Autant ne garder qu'une seule liaison entre un évènement et des gymnastes, et compléter ces enregistrements après (ou pendant) pour dire si Choupidou étant bien placé ou pas (quitte à laisser le `rank` vide si Choupidou n'est finalement pas venu ou s'il a sauté comme une bouse - oui, ça arrive).
|
||||
|
|
|
@ -7,5 +7,5 @@ from . import views
|
|||
|
||||
profile_urlpatterns = [
|
||||
path(r"lookup/", views.user_lookup, name="user_lookup"),
|
||||
path(r"edit/<int:profileid>/", views.profile_update, name="profile_update"),
|
||||
path(r"edit/", views.profile_update, name="profile_update"),
|
||||
]
|
||||
|
|
|
@ -60,17 +60,12 @@ def user_lookup(request):
|
|||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def profile_update(request, profileid):
|
||||
"""Modification d'un profil utilisateur.
|
||||
def profile_update(request):
|
||||
"""Modification du profil de l'utilisateur connecté
|
||||
|
||||
Args:
|
||||
profileid (int): L'identifiant du profil utilisateur à modifier.
|
||||
"""
|
||||
|
||||
profile = get_object_or_404(Profile, pk=profileid)
|
||||
|
||||
if profile.user != request.user:
|
||||
raise PermissionDenied("Permission denied : you don't have the permission to update this profile.")
|
||||
profile = request.user.profile
|
||||
|
||||
if request.method == "POST":
|
||||
form = ProfileForm(request.POST, instance=profile)
|
||||
|
@ -78,7 +73,6 @@ def profile_update(request, profileid):
|
|||
if form.is_valid():
|
||||
form.save()
|
||||
|
||||
request.session["profileid"] = profileid
|
||||
request.session["template"] = profile.template_color
|
||||
request.session["sidebar"] = profile.sidebar_color
|
||||
request.session["is_sidebar_minified"] = profile.is_sidebar_minified
|
||||
|
@ -88,5 +82,5 @@ def profile_update(request, profileid):
|
|||
else:
|
||||
form = ProfileForm(instance=profile)
|
||||
|
||||
context = {"form": form, "profileid": profileid}
|
||||
context = {"form": form,}
|
||||
return render(request, "profile_create.html", context)
|
||||
|
|
|
@ -87,93 +87,93 @@
|
|||
<i class="tim-icons icon-bullet-list-67 visible-on-sidebar-mini"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="navbar-toggle d-inline">
|
||||
<button type="button" class="navbar-toggler">
|
||||
<span class="navbar-toggler-bar bar1"></span>
|
||||
<span class="navbar-toggler-bar bar2"></span>
|
||||
<span class="navbar-toggler-bar bar3"></span>
|
||||
</button>
|
||||
</div>
|
||||
<a class="navbar-brand" href="/">Dashboard</a>
|
||||
</div>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-bar navbar-kebab"></span>
|
||||
<span class="navbar-toggler-bar navbar-kebab"></span>
|
||||
<span class="navbar-toggler-bar navbar-kebab"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navigation">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="search-bar input-group">
|
||||
<button class="btn btn-link" id="search-button" data-toggle="modal" data-target="#searchModal">
|
||||
<i class="tim-icons icon-zoom-split"></i>
|
||||
<span class="d-lg-none d-md-block">Search</span>
|
||||
<div class="navbar-toggle d-inline">
|
||||
<button type="button" class="navbar-toggler">
|
||||
<span class="navbar-toggler-bar bar1"></span>
|
||||
<span class="navbar-toggler-bar bar2"></span>
|
||||
<span class="navbar-toggler-bar bar3"></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="dropdown nav-item">
|
||||
<a href="javascript:void(0)" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
<i class="tim-icons icon-sound-wave"></i>
|
||||
<p class="d-lg-none">Flash access</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'calendar' %}" class="nav-item dropdown-item"><i class="far fa-calendar-alt"></i> Calendrier</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'chrono_create' %}" class="nav-item dropdown-item"><i class="far fa-stopwatch"></i> New chrono</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'score_create' %}" class="nav-item dropdown-item"><i class="far fa-share-alt"></i> New score</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="#" class="nav-item dropdown-item"><i class="far fa-bezier-curve"></i> Program</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown nav-item">
|
||||
<a href="javascript:void(0)" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
{% if number_unreaded_message %}
|
||||
<div class="notification d-none d-lg-block d-xl-block"></div>
|
||||
{% endif %}
|
||||
<i class="tim-icons icon-email-85"></i>
|
||||
<p class="d-lg-none">Notifications</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'compose_message' %}" class="nav-item dropdown-item"><i class="tim-icons icon-pencil"></i> Compose message</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'received_messages' %}" class="nav-item dropdown-item"><i class="tim-icons icon-email-85"></i> Received messages</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'sent_messages' %}" class="nav-item dropdown-item"><i class="tim-icons icon-send"></i> Sent messages</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown nav-item">
|
||||
<a href="#" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
<div class="photo">
|
||||
<img src="{% static '/img/mike.jpg' %}" alt="Profile Photo">
|
||||
</div>
|
||||
<b class="caret d-none d-lg-block d-xl-block"></b>
|
||||
<p class="d-lg-none">Log out</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'profile_update' request.session.profileid %}" class="nav-item dropdown-item">Profile</a>
|
||||
</li>
|
||||
<!-- <li class="nav-link"> -->
|
||||
</div>
|
||||
<a class="navbar-brand" href="/">Dashboard</a>
|
||||
</div>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-bar navbar-kebab"></span>
|
||||
<span class="navbar-toggler-bar navbar-kebab"></span>
|
||||
<span class="navbar-toggler-bar navbar-kebab"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navigation">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="search-bar input-group">
|
||||
<button class="btn btn-link" id="search-button" data-toggle="modal" data-target="#searchModal">
|
||||
<i class="tim-icons icon-zoom-split"></i>
|
||||
<span class="d-lg-none d-md-block">Search</span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="dropdown nav-item">
|
||||
<a href="javascript:void(0)" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
<i class="tim-icons icon-sound-wave"></i>
|
||||
<p class="d-lg-none">Flash access</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'calendar' %}" class="nav-item dropdown-item"><i class="far fa-calendar-alt"></i> Calendrier</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'chrono_create' %}" class="nav-item dropdown-item"><i class="far fa-stopwatch"></i> New chrono</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'score_create' %}" class="nav-item dropdown-item"><i class="far fa-share-alt"></i> New score</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="#" class="nav-item dropdown-item"><i class="far fa-bezier-curve"></i> Program</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown nav-item">
|
||||
<a href="javascript:void(0)" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
{% if number_unreaded_message %}
|
||||
<div class="notification d-none d-lg-block d-xl-block"></div>
|
||||
{% endif %}
|
||||
<i class="tim-icons icon-email-85"></i>
|
||||
<p class="d-lg-none">Notifications</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'compose_message' %}" class="nav-item dropdown-item"><i class="tim-icons icon-pencil"></i> Compose message</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'received_messages' %}" class="nav-item dropdown-item"><i class="tim-icons icon-email-85"></i> Received messages</a>
|
||||
</li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'sent_messages' %}" class="nav-item dropdown-item"><i class="tim-icons icon-send"></i> Sent messages</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown nav-item">
|
||||
<a href="#" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
<div class="photo">
|
||||
<img src="{% static '/img/mike.jpg' %}" alt="Profile Photo">
|
||||
</div>
|
||||
<b class="caret d-none d-lg-block d-xl-block"></b>
|
||||
<p class="d-lg-none">Log out</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'profile_update' %}" class="nav-item dropdown-item">Profile</a>
|
||||
</li>
|
||||
<!-- <li class="nav-link"> -->
|
||||
<!-- <a href="javascript:void(0)" class="nav-item dropdown-item">Settings</a> -->
|
||||
<!-- </li> -->
|
||||
<li class="dropdown-divider"></li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'logout' %}" class="nav-item dropdown-item">Log out</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="separator d-lg-none"></li>
|
||||
</ul>
|
||||
<!-- </li> -->
|
||||
<li class="dropdown-divider"></li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'logout' %}" class="nav-item dropdown-item">Log out</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="separator d-lg-none"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="modal modal-search fade" id="searchModal" tabindex="-1" role="dialog" aria-labelledby="searchModal" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
|
@ -237,7 +237,7 @@
|
|||
</div>
|
||||
<div class="togglebutton switch-change-color mt-3">
|
||||
<span class="label-switch">LIGHT MODE</span>
|
||||
<input type="checkbox" name="checkbox" {% if request.session.template == 0 %}checked{% endif %} class="bootstrap-switch" data-on-label="" data-off-label="" />
|
||||
<input type="checkbox" name="checkbox" {% if request.session.template == 0 %}checked{% endif %} class="bootstrap-switch" data-on-label="" data-off-label="" />
|
||||
<span class="label-switch label-right">DARK MODE</span>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -301,26 +301,22 @@
|
|||
$full_page = $('.full-page');
|
||||
$sidebar_responsive = $('body > .navbar-collapse');
|
||||
|
||||
{% if request.session.is_sidebar_minified %}sidebar_mini_active = true;
|
||||
{% else %}sidebar_mini_active = false;{% endif %}
|
||||
|
||||
|
||||
{% if request.session.template == 0%}white_color = false;
|
||||
{% else %}white_color = true;{% endif %}
|
||||
{% if request.session.is_sidebar_minified %}
|
||||
sidebar_mini_active = true; {% else %}
|
||||
sidebar_mini_active = false; {% endif %}
|
||||
{% if request.session.template == 0 %}
|
||||
white_color = false; {% else %}
|
||||
white_color = true; {% endif %}
|
||||
|
||||
window_width = $(window).width();
|
||||
|
||||
fixed_plugin_open = $('.sidebar .sidebar-wrapper .nav li.active a p').html();
|
||||
|
||||
{% if request.session.sidebar == 1 %}
|
||||
color = "blue";
|
||||
{% elif request.session.sidebar == 2 %}
|
||||
color = "green";
|
||||
{% elif request.session.sidebar == 3 %}
|
||||
color = "orange";
|
||||
{% elif request.session.sidebar == 4 %}
|
||||
color = "red";
|
||||
{% endif %}
|
||||
color = "blue"; {% elif request.session.sidebar == 2 %}
|
||||
color = "green"; {% elif request.session.sidebar == 3 %}
|
||||
color = "orange"; {% elif request.session.sidebar == 4 %}
|
||||
color = "red"; {% endif %}
|
||||
$sidebar.attr('data', color);
|
||||
$main_panel.attr('data', color);
|
||||
$full_page.attr('filter-color', color);
|
||||
|
@ -417,5 +413,6 @@
|
|||
|
||||
{% block footerscript %}{% endblock %}
|
||||
|
||||
</body>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -12,7 +12,7 @@
|
|||
<h4 class="card-title">Edit User Profile</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{% url 'profile_update' profileid %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||
<form action="{% url 'profile_update' %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<label for="id_birthdate" class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4 col-form-label">Birthdate</label>
|
||||
|
@ -59,10 +59,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" >
|
||||
$(function(){
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
blackDashboard.initDateTimePicker();
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue