f-string and notification refactoring

This commit is contained in:
Gregory Trullemans 2023-04-29 15:31:14 +02:00
parent 0ab362eb7c
commit 1998895e6d
11 changed files with 179 additions and 219 deletions

View File

@ -23,8 +23,8 @@ services:
- ./data:/var/lib/postgresql/data - ./data:/var/lib/postgresql/data
``` ```
- tapez la commande `docker-compose up -d` - tapez la commande `docker-compose up -d`
- `pip install -r requirements.txt`
- pip install -r requirements.txt - `python manage.py runserver`
### 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 :
@ -54,12 +54,14 @@ puis, **pour les mac M1** exécuter les commandes :
heroku config:set ALLOWED_HOSTS="avengers-jarvis.herokuapp.com" heroku config:set ALLOWED_HOSTS="avengers-jarvis.herokuapp.com"
heroku config:set SECRET_KEY="django-insecure-g_eoy6z%xshku4o5#k%o%i_%nb%_pz80config_#+t%f" heroku config:set SECRET_KEY="django-insecure-g_eoy6z%xshku4o5#k%o%i_%nb%_pz80config_#+t%f"
heroku config:set DATABASE_NAME="ultron" heroku config:set DATABASE_NAME="ultron"
``` ```
- Push de l'application : `git push heroku master`
- Se connecter à Héroku (via l'invite de commande) : `heroku login` - Se connecter à Héroku (via l'invite de commande) : `heroku login`
- Ajouter Heroku à Git : `git remote add heroku https://git.heroku.com/flying-ultron.git`
- Push de l'application : `git push heroku master`
- Création du super user : `heroku run python manage.py createsuperuser` - Création du super user : `heroku run python manage.py createsuperuser`

View File

@ -101,12 +101,7 @@ class Chrono(Seasonisable):
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
return "%s - %s (%s - %s)" % ( return f"{self.gymnast} - {self.score} ({self.date} - {self.chrono_type})"
self.gymnast,
self.score,
self.date,
self.chrono_type,
)
def timeline_representation(self): def timeline_representation(self):
return f"<li>{self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')</li>" return f"<li>{self.date:%d %b %Y} - New personel best {CHRONO_TYPE_CHOICE[self.chrono_type][1]}: {self.score}' ({self.tof}')</li>"
@ -167,10 +162,7 @@ class Accident(Markdownizable, Seasonisable):
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
return "%s (%s)" % ( return f"{self.gymnast} ({self.date})"
self.gymnast,
self.date,
)
def timeline_representation(self): def timeline_representation(self):
return f"<li>{self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)</li>" return f"<li>{self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)</li>"
@ -205,12 +197,7 @@ class LearnedSkill(Seasonisable):
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
return "%s - %s - %s - %s" % ( return f"{self.gymnast} - {self.date} - {self.learning_step} - {self.skill}"
self.gymnast,
self.date,
self.learning_step,
self.skill,
)
def timeline_representation(self): def timeline_representation(self):
return f"<li>{self.date:%d %b %Y} - learning of {self.skill.long_label} ({self.skill.short_label}): {LEARNING_STEP_CHOICES[self.learning_step][1]}</li>" return f"<li>{self.date:%d %b %Y} - learning of {self.skill.long_label} ({self.skill.short_label}): {LEARNING_STEP_CHOICES[self.learning_step][1]}</li>"
@ -247,11 +234,7 @@ class Plan(Seasonisable, Markdownizable):
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
return "%s - %s - %s" % ( return f"{self.gymnast} - {self.educative.short_label} - {self.date}"
self.gymnast,
self.educative.short_label,
self.date,
)
class Point(models.Model): class Point(models.Model):
@ -282,10 +265,7 @@ class Point(models.Model):
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated") updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated")
def __str__(self): def __str__(self):
return "%s - %s" % ( return f"{self.gymnast} - {self.total}"
self.gymnast,
self.total,
)
class MindState(Markdownizable, Seasonisable): class MindState(Markdownizable, Seasonisable):
@ -309,7 +289,7 @@ class MindState(Markdownizable, Seasonisable):
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
return "%s - %s : %s" % (self.gymnast, self.date, self.score) return f"{self.gymnast} - {self.date} : {self.score}"
class GymnastHasRoutine(models.Model): class GymnastHasRoutine(models.Model):
@ -343,7 +323,7 @@ class GymnastHasRoutine(models.Model):
date_end = models.DateField(verbose_name="Date end", null=True, blank=True) date_end = models.DateField(verbose_name="Date end", null=True, blank=True)
def __str__(self): def __str__(self):
return "%s - %s : %s" % (self.gymnast, self.routine_type, self.routine) return f"{self.gymnast} - {self.routine_type} : {self.routine}"
class NumberOfRoutineDone(Seasonisable): class NumberOfRoutineDone(Seasonisable):
@ -381,13 +361,7 @@ class NumberOfRoutineDone(Seasonisable):
) )
def __str__(self): def __str__(self):
return "%s - %s (%s) : %s | %s" % ( return f"{self.gymnast} - {self.routine_type} ({self.routine}) : {self.number_of_try} | {self.number_of_successes}"
self.gymnast,
self.routine_type,
self.routine,
self.number_of_try,
self.number_of_successes,
)
class HeightWeight(Seasonisable): class HeightWeight(Seasonisable):
@ -417,12 +391,7 @@ class HeightWeight(Seasonisable):
weight = models.DecimalField(max_digits=4, decimal_places=1, verbose_name="Weight") weight = models.DecimalField(max_digits=4, decimal_places=1, verbose_name="Weight")
def __str__(self): def __str__(self):
return "%s : %s/%s - %s" % ( return f"{self.gymnast} : {self.height}/{self.hips_height} - {self.weight}"
self.gymnast,
self.height,
self.hips_height,
self.weight,
)
class Note(Markdownizable, Seasonisable): class Note(Markdownizable, Seasonisable):
@ -448,7 +417,7 @@ class Note(Markdownizable, Seasonisable):
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
return "%s - %s : %s" % (self.gymnast, self.created_at, self.coach) return f"{self.gymnast} - {self.created_at} : {self.coach}"
class Intensity(Markdownizable, Seasonisable): class Intensity(Markdownizable, Seasonisable):
@ -480,14 +449,7 @@ class Intensity(Markdownizable, Seasonisable):
number_of_passes = models.PositiveSmallIntegerField() number_of_passes = models.PositiveSmallIntegerField()
def __str__(self): def __str__(self):
return "%s - %s : %s - %s - %s - %s" % ( return f"{self.gymnast} - {self.date} : {self.time} - {self.difficulty} - {self.quantity_of_skill} - {self.number_of_passes}"
self.gymnast,
self.date,
self.time,
self.difficulty,
self.quantity_of_skill,
self.number_of_passes,
)
@property @property
def mean_difficulty_by_passe(self): def mean_difficulty_by_passe(self):
@ -546,14 +508,7 @@ class SeasonInformation(models.Model):
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
def __str__(self): def __str__(self):
return "%s - %s : %s - %s - %s - %s" % ( return f"{self.gymnast} - {self.season} : {self.number_of_training_sessions_per_week} - {self.number_of_hours_per_week} - {self.category} - {self.club}"
self.gymnast,
self.season,
self.number_of_training_sessions_per_week,
self.number_of_hours_per_week,
self.category,
self.club,
)
class CompetitivePointsStats(Markdownizable, Seasonisable): class CompetitivePointsStats(Markdownizable, Seasonisable):

View File

@ -545,23 +545,24 @@ def chrono_create_or_update(request, chrono_id=None, gymnast_id=None):
new_chrono.save() new_chrono.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="chrono") functionality = ContentType.objects.get(model="chrono")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouveau chrono",
f"Un nouveau chrono enregistré pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouveau chrono",
[ f"Un nouveau chrono enregistré pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Un nouveau chrono enregistré pour {gymnast}.</p><br /> <p>Un nouveau chrono enregistré pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("gymnast_details_tab", args=(new_chrono.gymnast.id, "scores")) reverse("gymnast_details_tab", args=(new_chrono.gymnast.id, "scores"))
@ -627,23 +628,24 @@ def learnedskill_create_or_update(request, gymnast_id=None):
form.save() form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="learnedskill") functionality = ContentType.objects.get(model="learnedskill")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouveau skill appris",
f"Un nouveau skill a été appris par {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouveau skill appris",
[ f"Un nouveau skill a été appris par {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Un nouveau skill () a été appris par {gymnast}.</p><br /> <p>Un nouveau skill () a été appris par {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
@ -683,23 +685,24 @@ def score_create_or_update(request, score_id=None, gymnast_id=None):
form.save() form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="point") functionality = ContentType.objects.get(model="point")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouveau score enregistré",
f"Un nouveau score a été enregistré pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouveau score enregistré",
[ f"Un nouveau score a été enregistré pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Un nouveau score a été enregistré pour {gymnast}.</p><br /> <p>Un nouveau score a été enregistré pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
if form.cleaned_data["add_to_chrono"]: if form.cleaned_data["add_to_chrono"]:
new_chrono = Chrono( new_chrono = Chrono(
@ -806,23 +809,24 @@ def accident_create_or_update(request, accident_id=None, gymnast_id=None):
accident = form.save() accident = form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="accident") functionality = ContentType.objects.get(model="accident")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouvel accident enregistré",
f"Un nouvel accident enregistré pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouvel accident enregistré",
[ f"Un nouvel accident enregistré pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Un nouvel accident enregistré pour {gymnast}.</p><br /> <p>Un nouvel accident enregistré pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("accident_details", args=(accident.pk,)) reverse("accident_details", args=(accident.pk,))
@ -891,23 +895,24 @@ def mindstate_create_or_update(
mindstate = form.save() mindstate = form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="mindstate") functionality = ContentType.objects.get(model="mindstate")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouvel état d'esprit enregistré",
f"Un nouvel état d'esprit enregistré pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouvel état d'esprit enregistré",
[ f"Un nouvel état d'esprit enregistré pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Un nouvel état d'esprit enregistré pour {gymnast}.</p><br /> <p>Un nouvel état d'esprit enregistré pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("mindstate_details", args=(mindstate.pk,)) reverse("mindstate_details", args=(mindstate.pk,))
@ -976,23 +981,24 @@ def heightweight_create_or_update(request, heightweight_id=None, gymnast_id=None
form.save() form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="heightweight") functionality = ContentType.objects.get(model="heightweight")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouveau poids/taille enregistré",
f"Un nouveau poids/taille enregistré pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouveau poids/taille enregistré",
[ f"Un nouveau poids/taille enregistré pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Un nouveau poids/taille enregistré pour {gymnast}.</p><br /> <p>Un nouveau poids/taille enregistré pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse( reverse(
@ -1107,23 +1113,24 @@ def routinedone_create_or_update(request, routinedone_id=None, gymnast_id=None):
form.save() form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="numberofroutinedone") functionality = ContentType.objects.get(model="numberofroutinedone")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouvelle série comptabilisée",
f"Nouvelle série comptabilisée pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouvelle série comptabilisée",
[ f"Nouvelle série comptabilisée pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Nouvelle série comptabilisée pour {gymnast}.</p><br /> <p>Nouvelle série comptabilisée pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse( reverse(
@ -1179,23 +1186,24 @@ def plan_create_or_update(request, plan_id=None, gymnast_id=None, skill_id=None)
plan = form.save() plan = form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="plan") functionality = ContentType.objects.get(model="plan")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouvelle série comptabilisée",
f"Nouvelle série comptabilisée pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouvelle série comptabilisée",
[ f"Nouvelle série comptabilisée pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Nouvelle série comptabilisée pour {gymnast}.</p><br /> <p>Nouvelle série comptabilisée pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,))
@ -1270,23 +1278,24 @@ def intensity_create_or_update(request, intensity_id=None, gymnast_id=None):
intensity = form.save() intensity = form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="intensity") functionality = ContentType.objects.get(model="intensity")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouvelle intensité",
f"Une nouvelle note vous a été envoyée pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouvelle intensité",
[ f"Une nouvelle note vous a été envoyée pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Une nouvelle intensité a été encodée pour {gymnast}.</p><br /> <p>Une nouvelle intensité a été encodée pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse( reverse(
@ -1340,23 +1349,24 @@ def season_information_create_or_update(
season_information = form.save() season_information = form.save()
# notification # notification
receiver = []
gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id) gymnast = Gymnast.objects.get(pk=form.cleaned_data["gymnast"].id)
functionality = ContentType.objects.get(model="seasoninformation") functionality = ContentType.objects.get(model="seasoninformation")
for notification in gymnast.notifications.filter( for notification in gymnast.notifications.filter(
functionality=functionality functionality=functionality
): ):
send_mail( receiver.append(notification.user.email)
f"{gymnast} : Nouvelle information de saison",
f"Une nouvelle information de saison enregistrée pour {gymnast}", send_mail(
settings.EMAIL_HOST_USER, f"{gymnast} : Nouvelle information de saison",
[ f"Une nouvelle information de saison enregistrée pour {gymnast}",
notification.user.email, settings.EMAIL_HOST_USER,
], receiver,
fail_silently=False, fail_silently=False,
html_message=f"""<p>Bonjour,</p> html_message=f"""<p>Bonjour,</p>
<p>Une nouvelle information de saison enregistrée pour {gymnast}.</p><br /> <p>Une nouvelle information de saison enregistrée pour {gymnast}.</p><br />
<p>Excellente journée</p><p>Jarvis</p>""", <p>Excellente journée</p><p>Jarvis</p>""",
) )
return HttpResponseRedirect( return HttpResponseRedirect(
reverse( reverse(

View File

@ -19,7 +19,7 @@ class Country(models.Model):
isonum = models.PositiveSmallIntegerField() isonum = models.PositiveSmallIntegerField()
def __str__(self): def __str__(self):
return "%s (%s)" % (self.name, self.iso2) return f"{self.name} ({self.iso2})"
class Place(models.Model): class Place(models.Model):

View File

@ -102,11 +102,7 @@ class Educative(Markdownizable):
# is_competitive = models.BooleanField(default=False) # is_competitive = models.BooleanField(default=False)
def __str__(self): def __str__(self):
return "%s (%s - %s)" % ( return f"{self.long_label} ({self.short_label} - {self.difficulty})"
self.long_label,
self.short_label,
self.difficulty,
)
def breadcrumb(self, path=[]): def breadcrumb(self, path=[]):
""" """
@ -149,12 +145,7 @@ class PrerequisiteClosure(models.Model):
path = models.PositiveIntegerField() path = models.PositiveIntegerField()
def __str__(self): def __str__(self):
return "%s -> %s (%s|%s)" % ( return f"{self.ancestor.long_label} -> {self.descendant.long_label} ({self.level}|{self.path})"
self.ancestor.long_label,
self.descendant.long_label,
self.level,
self.path,
)
class TouchPosition(models.Model): class TouchPosition(models.Model):
@ -175,7 +166,7 @@ class TouchPosition(models.Model):
is_default = models.BooleanField(verbose_name="Défault ?", default=False) is_default = models.BooleanField(verbose_name="Défault ?", default=False)
def __str__(self): def __str__(self):
return "%s" % (self.long_label) return f"{self.long_label}"
def get_default_position(): def get_default_position():
@ -250,7 +241,7 @@ class Skill(Educative):
# importance = models.PositiveSmallIntegerField(default = 1) # importance = models.PositiveSmallIntegerField(default = 1)
def __str__(self): def __str__(self):
return "%s (%s)" % (self.long_label, self.notation) return f"{self.long_label} ({self.notation})"
class Routine(Educative): class Routine(Educative):
@ -270,7 +261,7 @@ class Routine(Educative):
is_competitive = models.BooleanField(default=False) is_competitive = models.BooleanField(default=False)
def __str__(self): def __str__(self):
return "%s (%s)" % (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.""" """Calcule les informations (rank, niveau, ages, …) d'une routine."""
@ -418,11 +409,7 @@ class RoutineSkill(models.Model):
rank = models.PositiveSmallIntegerField() rank = models.PositiveSmallIntegerField()
def __str__(self): def __str__(self):
return "%s - %s : %s" % ( return f"{self.rank} - {self.routine.short_label} : {self.skill.short_label}"
self.rank,
self.routine.short_label,
self.skill.short_label,
)
def max_even_if_none(value_1, value_2): def max_even_if_none(value_1, value_2):

View File

@ -4,12 +4,9 @@ from django.contrib.auth import get_user_model
from django.db.models import Count from django.db.models import Count
from django.db import models from django.db import models
User = get_user_model()
from datetime import date from datetime import date
import pendulum import pendulum
from jarvis.location.models import Club
from jarvis.objective.models import Skill from jarvis.objective.models import Skill
from jarvis.tools.models import Markdownizable from jarvis.tools.models import Markdownizable
from jarvis.objective.tools import ( from jarvis.objective.tools import (
@ -19,6 +16,8 @@ from jarvis.objective.tools import (
compute_statistics_by_type, compute_statistics_by_type,
) )
User = get_user_model()
GENDER_CHOICES = ((0, "Male"), (1, "Female")) GENDER_CHOICES = ((0, "Male"), (1, "Female"))
@ -56,7 +55,7 @@ class Gymnast(Markdownizable):
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
def __str__(self): def __str__(self):
return "%s %s" % (self.first_name, self.last_name) return f"{self.first_name} {self.last_name}"
@property @property
def next_birthday(self): def next_birthday(self):

View File

@ -1,6 +1,7 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.db.models import ( from django.db.models import (
Q, Q,
@ -41,10 +42,7 @@ from jarvis.followup.models import (
NumberOfRoutineDone, NumberOfRoutineDone,
) )
from jarvis.followup.models import ( from jarvis.followup.models import LEARNING_STEP_CHOICES
CATEGORY_CHOICES,
LEARNING_STEP_CHOICES,
)
from jarvis.tools.models import Season from jarvis.tools.models import Season
@ -391,11 +389,19 @@ def link_routine_to_gymnast(request, gymnast_id=None):
form.save() form.save()
if not gymnast: if not gymnast:
gymnast = get_object_or_404(Gymnast, pk=form.cleaned_data["gymnast"]) gymnast = get_object_or_404(Gymnast, pk=form.cleaned_data["gymnast"])
receiver = []
functionality = ContentType.objects.get(model="gymnasthasroutine")
for notification in gymnast.notifications.filter(
functionality=functionality
):
receiver.append(notification.user.email)
send_mail( send_mail(
"Nouvelle série", "Nouvelle série",
"Une nouvelle série vous a été associée.", "Une nouvelle série vous a été associée.",
settings.EMAIL_HOST_USER, settings.EMAIL_HOST_USER,
[gymnast.user.email, gymnast.email_trainer], [gymnast.user.email, gymnast.email_trainer].append(receiver),
fail_silently=False, fail_silently=False,
html_message="""<p>Bonjour,</p> html_message="""<p>Bonjour,</p>
<p>Une nouvelle série vous a été associée.</p><br /> <p>Une nouvelle série vous a été associée.</p><br />

View File

@ -44,7 +44,7 @@ class EventType(models.Model):
color = models.PositiveSmallIntegerField(choices=COLOR_CHOICES) color = models.PositiveSmallIntegerField(choices=COLOR_CHOICES)
def __str__(self): def __str__(self):
return "%s (%s)" % (self.name, self.acronym) return f"{self.name} ({self.acronym})"
class Event(Markdownizable, Temporizable): class Event(Markdownizable, Temporizable):
@ -74,7 +74,7 @@ class Event(Markdownizable, Temporizable):
) )
def __str__(self): def __str__(self):
return "%s%s)" % (self.name, self.place) return f"{self.name}{self.place})"
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.checkdates() self.checkdates()
@ -105,4 +105,4 @@ class EventParticipation(models.Model):
rank = models.PositiveSmallIntegerField(default=0) rank = models.PositiveSmallIntegerField(default=0)
def __str__(self): def __str__(self):
return "%s to %s" % (self.gymnast, self.event) return f"{self.gymnast} to {self.event}"

View File

@ -41,7 +41,7 @@ class Profile(models.Model):
is_sidebar_minified = models.BooleanField(default=False) is_sidebar_minified = models.BooleanField(default=False)
def __str__(self): def __str__(self):
return "%s %s" % (self.user.first_name, self.user.last_name) return f"{self.user.first_name} {self.user.last_name}"
class Notification(models.Model): class Notification(models.Model):

View File

@ -16,9 +16,10 @@
<div class="table-responsive"> <div class="table-responsive">
{% for gymnast in gymnast_list %} {% for gymnast in gymnast_list %}
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-md-8">
<b>{{ gymnast }}</b> <b>{{ gymnast }}</b>
</div> </div>
<div class="col-md-3 ml-3"></div>
</div> </div>
<div class="row"> <div class="row">
{% for functionality in functionality_list %} {% for functionality in functionality_list %}
@ -54,7 +55,7 @@
csrfmiddlewaretoken: '{{ csrf_token }}' csrfmiddlewaretoken: '{{ csrf_token }}'
}, },
success: function(data) { success: function(data) {
alert("Demande de notification ajoutée."); // alert("Demande de notification ajoutée.");
} }
}); });
@ -68,7 +69,7 @@
csrfmiddlewaretoken: '{{ csrf_token }}' csrfmiddlewaretoken: '{{ csrf_token }}'
}, },
success: function(data) { success: function(data) {
alert("Demande de notification supprimée."); // alert("Demande de notification supprimée.");
} }
}); });
} }

View File

@ -71,7 +71,7 @@ class Season:
return True return True
def __str__(self): def __str__(self):
return "%s" % (self.label) return f"{self.label}"
def get_default_date(): def get_default_date():