Tronquer les titres d'établissements dans le formulaire du chercheur.
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / forms.py
1 # -*- encoding: utf-8 -*-
2 import hashlib
3 from django import forms
4 from django.db.models import Q
5 from models import *
6
7 class PersonneForm(forms.ModelForm):
8 genre = forms.ChoiceField(widget=forms.RadioSelect(), choices=GENRE_CHOICES)
9
10 class Meta:
11 model = Utilisateur
12 fields = ('nom', 'prenom', 'courriel', 'genre')
13
14 class PersonneInscriptionForm(PersonneForm):
15 password = forms.CharField(widget=forms.PasswordInput(), label="Mot de passe")
16
17 class Meta(PersonneForm.Meta):
18 fields = ('nom', 'prenom', 'courriel', 'password', 'genre')
19
20 def clean_password(self):
21 """Encrypter le mot de passe avant de le mettre dans la BD."""
22 return hashlib.md5(self.cleaned_data['password']).hexdigest()
23
24 class ChercheurForm(forms.ModelForm):
25 """Formulaire d'édition d'un chercheur."""
26 OUI_NON_CHOICES = ((1, 'Oui'), (0, 'Non'))
27 ETABLISSEMENT_CHOICES = ((id, nom if len(nom) < 80 else nom[:80] + '...')
28 for id, nom in Etablissement.objects.values_list('id', 'nom'))
29
30 membre_instance_auf = forms.ChoiceField(
31 choices=OUI_NON_CHOICES,
32 label="Êtes-vous (ou avez-vous déjà été) membre d'une instance de l'AUF?",
33 help_text="e.g. conseil scientifique, conseil associatif, commission régionale d'experts",
34 widget=forms.RadioSelect()
35 )
36 membre_instance_auf_dates = forms.CharField(label="Préciser les dates", required=False)
37 expert_oif = forms.ChoiceField(choices=OUI_NON_CHOICES,
38 label="Êtes-vous expert de l'OIF?",
39 widget=forms.RadioSelect())
40 membre_fipf = forms.ChoiceField(choices=OUI_NON_CHOICES,
41 label="Êtes-vous membre de la FIPF?",
42 widget=forms.RadioSelect())
43 membre_fipf_association = forms.CharField(label="Préciser le nom de votre association", required=False)
44 etablissement = forms.ChoiceField(label='Etablissement', choices=ETABLISSEMENT_CHOICES)
45
46 class Meta:
47 model = Chercheur
48 fields = ('statut', 'diplome', 'etablissement',
49 'etablissement_autre_nom', 'etablissement_autre_pays',
50 'discipline', 'theme_recherche', 'groupe_recherche', 'mots_cles',
51 'url_site_web', 'url_blog', 'url_reseau_social',
52 'membre_instance_auf', 'membre_instance_auf_dates',
53 'expert_oif', 'membre_fipf', 'membre_fipf_association')
54
55 def clean_etablissement(self):
56 return Etablissement.objects.get(id=self.cleaned_data['etablissement'])
57
58 def clean(self):
59 etablissement = self.cleaned_data['etablissement']
60 etablissement_autre_nom = self.cleaned_data['etablissement_autre_nom']
61 etablissement_autre_pays = self.cleaned_data['etablissement_autre_pays']
62 if not etablissement:
63 if not etablissement_autre_nom:
64 self._errors['etablissement'] = self.error_class([u"Vous devez renseigner l'établissement"])
65 elif not etablissement_autre_pays:
66 self._errors['etablissement_autre_pays'] = self.error_class([u"Vous devez renseigner le pays de l'établissement"])
67 return self.cleaned_data
68
69 def clean_membre_instance_auf(self):
70 """Transforme la valeur du champ en booléen"""
71 return bool(int(self.cleaned_data['membre_instance_auf']))
72
73 def clean_expert_oif(self):
74 """Transforme la valeur du champ en booléen"""
75 return bool(int(self.cleaned_data['expert_oif']))
76
77 def clean_membre_fipf(self):
78 """Transforme la valeur du champ en booléen"""
79 return bool(int(self.cleaned_data['membre_fipf']))
80
81 class GroupesForm(forms.Form):
82 """Formulaire qui associe des groupes à un chercheur."""
83 groupes = forms.ModelMultipleChoiceField(
84 queryset=Groupe.objects.all(),
85 label='Domaines de recherche', required=False,
86 help_text="Maintenez appuyé « Ctrl », ou « Commande (touche pomme) » sur un Mac, pour en sélectionner plusieurs."
87 )
88
89 def __init__(self, data=None, prefix=None, chercheur=None):
90 self.chercheur = chercheur
91 initial = {}
92 if chercheur:
93 initial['groupes'] = chercheur.groupes.values_list('id', flat=True)
94 super(GroupesForm, self).__init__(data=data, prefix=prefix, initial=initial)
95
96 def save(self):
97 if self.is_valid():
98 groupes = self.cleaned_data['groupes']
99 ChercheurGroupe.objects.filter(chercheur=self.chercheur).exclude(groupe__in=groupes).delete()
100 for g in groupes:
101 ChercheurGroupe.objects.get_or_create(chercheur=self.chercheur, groupe=g, actif=1)
102
103 class PublicationForm(forms.ModelForm):
104 class Meta:
105 model = Publication
106 fields = ('titre', 'annee', 'revue', 'editeur', 'lieu_edition', 'nb_pages', 'url')
107
108 class TheseForm(PublicationForm):
109 titre = forms.CharField(required=True, label="Titre de la thèse ou du mémoire")
110 annee = forms.IntegerField(required=True, label="Année de soutenance (réalisée ou prévue)")
111 editeur = forms.CharField(required=True, label="Directeur de thèse")
112 lieu_edition = forms.CharField(required=True, label="Établissement de soutenance")
113 class Meta:
114 model = Publication
115 fields = ('titre', 'annee', 'editeur', 'lieu_edition', 'nb_pages', 'url')
116
117 class ExpertiseForm(forms.ModelForm):
118 OUI_NON_CHOICES = ((1, 'Oui'), (0, 'Non'))
119 organisme_demandeur_visible = forms.ChoiceField(choices=OUI_NON_CHOICES,
120 required=False,
121 label="Voulez-vous que l'organisme demandeur soit visible sur votre fiche?",
122 widget=forms.RadioSelect())
123 class Meta:
124 model = Expertise
125 fields = ('nom', 'date', 'organisme_demandeur', 'organisme_demandeur_visible')
126
127 def clean_organisme_demandeur_visible(self):
128 """Transforme la valeur du champ en booléen"""
129 value = self.cleaned_data['organisme_demandeur_visible']
130 return bool(int(value)) if value else False
131
132 class ChercheurFormGroup(object):
133 """Groupe de formulaires nécessaires pour l'inscription et l'édition
134 d'un chercheur."""
135
136 def __init__(self, data=None, chercheur=None):
137 personne_form_class = PersonneInscriptionForm if chercheur is None else PersonneForm
138 self.chercheur = ChercheurForm(data=data, prefix='chercheur', instance=chercheur)
139 self.groupes = GroupesForm(data=data, prefix='chercheur', chercheur=chercheur)
140 self.personne = personne_form_class(data=data, prefix='personne', instance=chercheur and chercheur.personne)
141 self.publication1 = PublicationForm(data=data, prefix='publication1', instance=chercheur and chercheur.publication1)
142 self.publication2 = PublicationForm(data=data, prefix='publication2', instance=chercheur and chercheur.publication2)
143 self.publication3 = PublicationForm(data=data, prefix='publication3', instance=chercheur and chercheur.publication3)
144 self.publication4 = PublicationForm(data=data, prefix='publication4', instance=chercheur and chercheur.publication4)
145 self.these = TheseForm(data=data, prefix='these', instance=chercheur and chercheur.these)
146 self.expertise = ExpertiseForm(data=data, prefix='expertise', instance=chercheur and chercheur.expertise)
147
148 @property
149 def has_errors(self):
150 return bool(self.chercheur.errors or self.personne.errors or self.groupes.errors or
151 self.publication1.errors or self.publication2.errors or self.publication3.errors or
152 self.publication4.errors or self.these.errors or self.expertise.errors)
153
154 def is_valid(self):
155 return self.chercheur.is_valid() and self.personne.is_valid() and self.groupes.is_valid() and \
156 self.publication1.is_valid() and self.publication2.is_valid() and \
157 self.publication3.is_valid() and self.publication4.is_valid() and \
158 self.these.is_valid() and self.expertise.is_valid()
159
160 def save(self):
161 if self.is_valid():
162
163 chercheur = self.chercheur.instance
164
165 # Enregistrer d'abord les clés étrangères car on doit les stocker dans
166 # l'objet chercheur.
167 chercheur.personne = self.personne.save()
168 if self.publication1.cleaned_data['titre']:
169 chercheur.publication1 = self.publication1.save()
170 if self.publication2.cleaned_data['titre']:
171 chercheur.publication2 = self.publication2.save()
172 if self.publication3.cleaned_data['titre']:
173 chercheur.publication3 = self.publication3.save()
174 if self.publication4.cleaned_data['titre']:
175 chercheur.publication4 = self.publication4.save()
176 chercheur.these = self.these.save()
177 if self.expertise.cleaned_data['nom']:
178 chercheur.expertise = self.expertise.save()
179
180 # Puis enregistrer le chercheur lui-même.
181 self.chercheur.save()
182
183 # Puis les many-to-many puisqu'on a besoin d'un id.
184 self.groupes.chercheur = chercheur
185 self.groupes.save()
186
187 class RepertoireSearchForm (forms.Form):
188 mots_cles = forms.CharField(required=False, label="Rechercher dans tous les champs")
189 nom = forms.CharField(required=False, label="Nom")
190 discipline = forms.ModelChoiceField(queryset=Discipline.objects.all(), required=False, label="Discipline", empty_label="Tous")
191 domaine = forms.ModelChoiceField(queryset=Groupe.objects.all(), required=False, label="Domaine de recherche", empty_label="Tous")
192 groupe_recherche = forms.CharField(required=False, label="Groupe de recherche")
193 statut = forms.ChoiceField(choices=(('','Tous'),)+STATUT_CHOICES+(('expert','Expert'),), required=False, label="Statut")
194 pays = forms.ModelChoiceField(queryset=Pays.objects.all(), required=False, label="Pays", empty_label="Tous")
195 region = forms.ModelChoiceField(queryset=Region.objects.all(), required=False, label="Région", empty_label="Toutes")
196 nord_sud = forms.ChoiceField(choices=(('', 'Tous'), ('Nord', 'Nord'), ('Sud', 'Sud')), required=False, label="Nord/Sud")
197
198 def get_query_set(self):
199 qs = Chercheur.objects.all()
200 if self.is_valid():
201 nom = self.cleaned_data['nom']
202 if nom:
203 qs = qs.search_nom(nom)
204 discipline = self.cleaned_data["discipline"]
205 if discipline:
206 qs = qs.filter(discipline=discipline)
207 domaine = self.cleaned_data["domaine"]
208 if domaine:
209 qs = qs.filter(groupes=domaine)
210 groupe_recherche = self.cleaned_data['groupe_recherche']
211 if groupe_recherche:
212 for word in groupe_recherche.split():
213 qs = qs.filter(groupe_recherche__icontains=word)
214 mots_cles = self.cleaned_data["mots_cles"]
215 if mots_cles:
216 qs = qs.search(mots_cles)
217 statut = self.cleaned_data["statut"]
218 if statut:
219 if statut == "expert":
220 qs = qs.exclude(expertise=None)
221 else:
222 qs = qs.filter(statut=statut)
223 pays = self.cleaned_data["pays"]
224 if pays:
225 qs = qs.filter(Q(etablissement__pays=pays) | Q(etablissement_autre_pays=pays))
226 region = self.cleaned_data['region']
227 if region:
228 qs = qs.filter(Q(etablissement__pays__region=region) | Q(etablissement_autre_pays__region=region))
229 nord_sud = self.cleaned_data['nord_sud']
230 if nord_sud:
231 qs = qs.filter(Q(etablissement__pays__nord_sud=nord_sud) | Q(etablissement_autre_pays__nord_sud=nord_sud))
232 return qs
233
234 class SendPasswordForm(forms.Form):
235 email = forms.EmailField(required=True, label="Adresse électronique")
236 def clean_email(self):
237 cleaned_data = self.cleaned_data
238 email = cleaned_data.get("email")
239 if email:
240 try:
241 Utilisateur.objects.get(courriel=email)
242 except:
243 raise forms.ValidationError("Cette adresse n'existe pas dans notre base de données.")
244 return email
245
246 class NewPasswordForm(forms.Form):
247 password = forms.CharField(widget=forms.PasswordInput(), required=True, label="Mot de passe")
248 password_repeat = forms.CharField(widget=forms.PasswordInput(), required=True, label="Confirmez mot de passe")
249 def clean_password_repeat(self):
250 cleaned_data = self.cleaned_data
251 password = cleaned_data.get("password")
252 password_repeat = cleaned_data.get("password_repeat")
253 if password and password_repeat:
254 if password != password_repeat:
255 raise forms.ValidationError("Les mots de passe ne concordent pas")
256 return password_repeat
257