experiENS/avisstage/forms.py

199 lines
7.3 KiB
Python
Raw Normal View History

2021-02-07 00:44:58 +01:00
import re
import unicodedata
2021-02-07 00:44:58 +01:00
from simple_email_confirmation.models import EmailAddress
from django import forms
from django.contrib.auth.forms import PasswordResetForm
from django.utils import timezone
2021-02-07 00:44:58 +01:00
from .models import AvisLieu, AvisStage, Lieu, Normalien, Stage, User
2017-05-02 23:23:26 +02:00
from .widgets import LatLonField
2021-02-07 00:44:58 +01:00
2017-05-02 23:23:26 +02:00
# Sur-classe utile
2017-04-15 20:03:08 +02:00
class HTMLTrimmerForm(forms.ModelForm):
def clean(self):
2017-05-02 23:23:26 +02:00
# Suppression des espaces blanc avant et après le texte pour les champs html
2021-02-07 00:41:22 +01:00
leading_white = re.compile(
r"^( \t\n)*(<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>( \t\n)*)+?", re.IGNORECASE
)
trailing_white = re.compile(
r"(( \t\n)*<p>(&nbsp;|[ \n\t]|<br[ /]*>)*</p>)+?( \t\n)*$", re.IGNORECASE
)
2017-04-15 20:03:08 +02:00
cleaned_data = super(HTMLTrimmerForm, self).clean()
2021-02-07 00:41:22 +01:00
2017-04-15 20:03:08 +02:00
for (fname, fval) in cleaned_data.items():
2017-05-02 23:23:26 +02:00
# Heuristique : les champs commençant par "avis_" sont des champs html
2017-04-15 20:03:08 +02:00
if fname[:5] == "avis_":
2021-02-07 00:41:22 +01:00
cleaned_data[fname] = leading_white.sub(
"", trailing_white.sub("", fval)
)
2017-04-15 20:03:08 +02:00
return cleaned_data
2021-02-07 00:41:22 +01:00
2017-05-02 23:23:26 +02:00
# Infos sur un stage
class StageForm(forms.ModelForm):
2021-02-07 00:41:22 +01:00
date_widget = forms.DateInput(
attrs={"class": "datepicker", "placeholder": "JJ/MM/AAAA"}
)
date_debut = forms.DateField(
label="Date de début", input_formats=["%d/%m/%Y"], widget=date_widget
)
date_fin = forms.DateField(
label="Date de fin", input_formats=["%d/%m/%Y"], widget=date_widget
)
2017-05-02 23:23:26 +02:00
class Meta:
model = Stage
2021-02-07 00:41:22 +01:00
fields = [
"sujet",
"date_debut",
"date_fin",
"type_stage",
"niveau_scol",
"thematiques",
"matieres",
"structure",
"encadrants",
]
2017-05-02 23:23:26 +02:00
help_texts = {
2021-02-07 00:40:55 +01:00
"thematiques": "Mettez une virgule pour valider votre thématique si la suggestion ne correspond pas ou si elle n'existe pas encore",
2021-02-07 00:41:22 +01:00
"structure": "Nom de l'équipe, du laboratoire, de la startup... (si le lieu ne suffit pas)",
2017-05-02 23:23:26 +02:00
}
labels = {
2021-02-07 00:40:55 +01:00
"date_debut": "Date de début",
2017-05-02 23:23:26 +02:00
}
def __init__(self, *args, **kwargs):
# Sauvegarde de la request pour avoir l'user
if "request" in kwargs:
self.request = kwargs.pop("request")
super(StageForm, self).__init__(*args, **kwargs)
2021-02-07 00:41:22 +01:00
2017-05-02 23:23:26 +02:00
def save(self, commit=True):
# Lors de la création : attribution à l'utilisateur connecté
2021-02-07 00:41:22 +01:00
if self.instance.id is None and hasattr(self, "request"):
2017-05-02 23:23:26 +02:00
self.instance.auteur = self.request.user.profil
2021-02-07 00:41:22 +01:00
2017-05-02 23:23:26 +02:00
# Date de modification
self.instance.date_maj = timezone.now()
self.instance.update_stats(False)
2021-02-07 00:41:22 +01:00
2017-05-02 23:23:26 +02:00
stage = super(StageForm, self).save(commit=commit)
return stage
2021-02-07 00:41:22 +01:00
2017-05-02 23:23:26 +02:00
# Sous-formulaire des avis sur le stage
2017-04-15 20:03:08 +02:00
class AvisStageForm(HTMLTrimmerForm):
2017-04-13 22:50:00 +02:00
class Meta:
model = AvisStage
2021-02-07 00:41:22 +01:00
fields = [
"chapo",
"avis_sujet",
"avis_ambiance",
"avis_admin",
"avis_prestage",
"les_plus",
"les_moins",
]
2017-04-15 20:03:08 +02:00
help_texts = {
2021-02-07 00:41:22 +01:00
"chapo": '"Trop long, pas lu" : une accroche résumant ce que vous avez pensé de ce séjour',
2021-02-07 00:40:55 +01:00
"avis_ambiance": "Avez-vous passé un bon moment à ce travail ? Étiez-vous assez guidé⋅e ? Aviez-vous un bon contact avec vos encadrant⋅e⋅s ? Y avait-il une bonne ambiance dans l'équipe ?",
"avis_sujet": "Quelle était votre mission ? Qu'en avez-vous retiré ? Le travail correspondait-il à vos attentes ? Était-ce à votre niveau, trop dur, trop facile ?",
"avis_admin": "Avez-vous commencé votre travail à la date prévue ? Était-ce compliqué d'obtenir les documents nécessaires (visa, contrats, etc) ? L'administration de l'établissement vous a-t-elle aidé⋅e ? Étiez-vous rémunéré⋅e ?",
"avis_prestage": "Comment avez-vous trouvé où aller pour cette expérience ? À quel moment avez-vous commencé à chercher ? Avez-vous eu des entretiens pour obtenir votre place ? Avez-vous eu d'autres pistes, pourquoi avez-vous choisi cette option ?",
"les_plus": "Les principaux points positifs de cette expérience",
"les_moins": "Ce qui aurait pu être mieux",
2017-04-15 20:03:08 +02:00
}
2017-04-13 22:50:00 +02:00
2021-02-07 00:41:22 +01:00
2017-04-15 20:03:08 +02:00
class AvisLieuForm(HTMLTrimmerForm):
2017-04-13 22:50:00 +02:00
class Meta:
model = AvisLieu
2021-02-07 00:41:22 +01:00
fields = [
"lieu",
"chapo",
"avis_lieustage",
"avis_pratique",
"avis_tourisme",
"les_plus",
"les_moins",
]
2017-04-15 20:03:08 +02:00
help_texts = {
2021-02-07 00:41:22 +01:00
"chapo": '"Trop long, pas lu" : une accroche résumant ce que vous avez pensé de cet endroit',
2021-02-07 00:40:55 +01:00
"avis_lieustage": "Qu'avez-vous pensé des lieux où vous travailliez ? Les bâtiments étaient-ils modernes ? Était-il agréable d'y travailler ?",
"avis_pratique": "Avez-vous eu du mal à trouver un logement ? Y-a-t-il des choses que vous avez apprises sur place qu'il vous aurait été utile de savoir avant de partir ?",
"avis_tourisme": "Y-a-t-il des lieux à visiter dans cette zone ? Avez-vous pratiqué des activités sportives ? Est-il facile de faire des rencontres ?",
"les_plus": "Les meilleures raisons de partir à cet endroit",
"les_moins": "Ce qui vous a gêné ou manqué là-bas",
2017-04-15 20:03:08 +02:00
}
2021-02-07 00:41:22 +01:00
widgets = {"lieu": forms.HiddenInput(attrs={"class": "lieu-hidden"})}
2017-04-13 22:50:00 +02:00
2017-05-02 23:23:26 +02:00
# Création d'un nouveau lieu
class LieuForm(forms.ModelForm):
coord = LatLonField()
id = forms.IntegerField(widget=forms.widgets.HiddenInput(), required=False)
2021-02-07 00:41:22 +01:00
class Meta:
model = Lieu
2021-02-07 00:41:22 +01:00
fields = ["id", "nom", "type_lieu", "ville", "pays", "coord"]
2017-05-02 23:23:26 +02:00
# Widget de feedback
2017-04-20 23:04:07 +02:00
class FeedbackForm(forms.Form):
objet = forms.CharField(label="Objet", required=True)
2021-02-07 00:41:22 +01:00
message = forms.CharField(
label="Message", required=True, widget=forms.widgets.Textarea()
)
# Nouvelle adresse mail
class AdresseEmailForm(forms.Form):
def __init__(self, _user, **kwargs):
self._user = _user
super().__init__(**kwargs)
2021-02-07 00:41:22 +01:00
email = forms.EmailField(
widget=forms.widgets.EmailInput(attrs={"placeholder": "Nouvelle adresse"})
)
def clean_email(self):
email = self.cleaned_data["email"]
if EmailAddress.objects.filter(user=self._user, email=email).exists():
2021-02-07 00:41:22 +01:00
raise forms.ValidationError("Cette adresse est déjà associée à ce compte")
return email
def _unicode_ci_compare(s1, s2):
"""
Perform case-insensitive comparison of two identifiers, using the
recommended algorithm from Unicode Technical Report 36, section
2.11.2(B)(2).
"""
2021-02-07 00:41:22 +01:00
return (
unicodedata.normalize("NFKC", s1).casefold()
== unicodedata.normalize("NFKC", s2).casefold()
)
# (Ré)initialisation du mot de passe
class ReinitMdpForm(PasswordResetForm):
def get_users(self, email):
"""Override default method to allow unusable passwords"""
email_field_name = User.get_email_field_name()
2021-02-07 00:41:22 +01:00
active_users = User._default_manager.filter(
**{
"%s__iexact" % email_field_name: email,
"is_active": True,
}
)
return (
2021-02-07 00:41:22 +01:00
u
for u in active_users
if _unicode_ci_compare(email, getattr(u, email_field_name))
)