Modification User.email modifi personne.courriel au besoin
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / models.py
1 # -*- encoding: utf-8 -*-
2 import hashlib
3
4 from datamaster_modeles.models import *
5 from django.conf import settings
6 from django.contrib.auth.models import User
7 from django.core.urlresolvers import reverse as url
8 from django.db import models
9 from django.db.models import Q
10 from django.utils.encoding import smart_str
11 from django.utils.hashcompat import sha_constructor
12 from django.db.models.signals import post_save
13 from djangosphinx.models import SphinxSearch
14
15 from savoirs.models import Discipline, SEPManager, SEPSphinxQuerySet, SEPQuerySet, Search
16
17 GENRE_CHOICES = (('m', 'Homme'), ('f', 'Femme'))
18 class Personne(models.Model):
19 user = models.OneToOneField(User, related_name="chercheur", verbose_name="utilisateur", null=True, blank=True)
20 salutation = models.CharField(max_length=128, null=True, blank=True)
21 nom = models.CharField(max_length=255)
22 prenom = models.CharField(max_length=128, verbose_name='prénom')
23 courriel = models.EmailField(max_length=128, verbose_name="courriel")
24 afficher_courriel = models.BooleanField(default=True)
25 fonction = models.CharField(max_length=128, null=True, blank=True)
26 date_naissance = models.DateField(null=True, blank=True)
27 sousfonction = models.CharField(max_length=128, null=True, blank=True, verbose_name='sous-fonction')
28 telephone = models.CharField(max_length=32, null=True, blank=True, verbose_name='numéro de téléphone')
29 adresse_postale = models.TextField(blank=True)
30 genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
31 commentaire = models.TextField(verbose_name='commentaires', null=True, blank=True)
32 actif = models.BooleanField(editable=False, default=False)
33
34 def __unicode__(self):
35 return u"%s %s, %s" % (self.prenom, self.nom, self.courriel)
36
37 class Meta:
38 ordering = ["nom", "prenom"]
39
40 def save(self, *args, **kwargs):
41
42 try:
43 old_instance = Personne.objects.get(pk=self.pk)
44 if self.courriel != old_instance.courriel:
45 try:
46 user = User.objects.get(email=old_instance.courriel)
47 user.email = self.courriel
48 user.save()
49 except User.DoesNotExist:
50 pass
51 except Personne.DoesNotExist:
52 pass
53
54 super(Personne, self).save(*args, **kwargs)
55
56 @property
57 def civilite(self):
58 if self.genre == 'm':
59 return 'M.'
60 elif self.genre == 'f':
61 return 'Mme'
62 else:
63 return ''
64
65 @property
66 def prenom_nom(self):
67 return u"%s %s" % (self.prenom, self.nom)
68
69 def courriel_display(self):
70 return self.courriel.replace(u'@', u' (à) ')
71
72
73 def change_personne_courriel(sender, **kwargs):
74 user = kwargs['instance']
75 try:
76 if user.chercheur:
77 if user.email != user.chercheur.courriel:
78 chercheur = user.chercheur
79 chercheur.courriel = user.email
80 chercheur.save()
81 except:
82 pass
83
84 post_save.connect(change_personne_courriel, sender=User)
85
86
87 class ChercheurQuerySet(SEPQuerySet):
88
89 def filter_groupe(self, groupe):
90 return self.filter(groupes=groupe)
91
92 def filter_pays(self, pays):
93 return self.filter(Q(etablissement__pays=pays) | Q(etablissement_autre_pays=pays))
94
95 def filter_region(self, region):
96 return self.filter(Q(etablissement__pays__region=region) | Q(etablissement_autre_pays__region=region))
97
98 def filter_nord_sud(self, nord_sud):
99 return self.filter(Q(etablissement__pays__nord_sud=nord_sud) | Q(etablissement_autre_pays__nord_sud=nord_sud))
100
101 def filter_genre(self, genre):
102 return self.filter(genre=genre)
103
104 def filter_statut(self, statut):
105 return self.filter(statut=statut)
106
107 def filter_expert(self):
108 return self.exclude(expertises=None)
109
110 def filter_date_modification(self, min=None, max=None):
111 return self._filter_date('date_modification', min=min, max=max)
112
113 def order_by_nom(self, direction=''):
114 return self.order_by(direction + 'nom', direction + 'prenom', '-date_modification')
115
116 def order_by_etablissement(self, direction=''):
117 return self.extra(select=dict(etablissement_nom='IFNULL(ref_etablissement.nom, chercheurs_chercheur.etablissement_autre_nom)'),
118 order_by=[direction + 'etablissement_nom', '-date_modification'])
119
120 def order_by_pays(self, direction=''):
121 return self.extra(select=dict(
122 pays_etablissement='''(SELECT nom FROM ref_pays
123 WHERE ref_pays.code = IFNULL(ref_etablissement.pays, chercheurs_chercheur.etablissement_autre_pays))'''
124 ), order_by=[direction + 'pays_etablissement', '-date_modification'])
125
126 class ChercheurSphinxQuerySet(SEPSphinxQuerySet):
127
128 def __init__(self, model=None):
129 return SEPSphinxQuerySet.__init__(self, model=model, index='savoirsenpartage_chercheurs',
130 weights=dict(nom=2, prenom=2))
131
132 def filter_region(self, region):
133 return self.filter(region_id=region.id)
134
135 def filter_discipline(self, discipline):
136 return self.filter(discipline_id=discipline.id)
137
138 def filter_groupe(self, groupe):
139 return self.filter(groupe_ids=groupe.id)
140
141 def filter_pays(self, pays):
142 return self.filter(pays_id=pays.id)
143
144 NORD_SUD_CODES = {'Nord': 1, 'Sud': 2}
145 def filter_nord_sud(self, nord_sud):
146 return self.filter(nord_sud=self.NORD_SUD_CODES[nord_sud])
147
148 GENRE_CODES = dict([(k, i+1) for i, (k, v) in enumerate(GENRE_CHOICES)])
149 def filter_genre(self, genre):
150 return self.filter(genre=self.GENRE_CODES[genre])
151
152 STATUT_CODES = {'enseignant': 1, 'etudiant': 2, 'independant': 3}
153 def filter_statut(self, statut):
154 return self.filter(statut=self.STATUT_CODES[statut])
155
156 def filter_expert(self):
157 return self.filter(expert=True)
158
159 def filter_date_modification(self, min=None, max=None):
160 return self._filter_date('date_modification', min=min, max=max)
161
162 def order_by_nom(self, direction=''):
163 return self.order_by(direction + 'nom_complet', '-date_modification')
164
165 def order_by_etablissement(self, direction=''):
166 return self.order_by(direction + 'etablissement_attr', '-date_modification')
167
168 def order_by_pays(self, direction=''):
169 return self.order_by(direction + 'pays_attr', '-date_modification')
170
171 class ChercheurManager(SEPManager):
172
173 def get_query_set(self):
174 return ChercheurQuerySet(self.model).filter(actif=True)
175
176 def get_sphinx_query_set(self):
177 return ChercheurSphinxQuerySet(self.model).order_by('-date_modification')
178
179 def filter_region(self, region):
180 """Le filtrage de chercheurs par région n'est pas une recherche texte."""
181 return self.get_query_set().filter_region(region)
182
183 def filter_groupe(self, groupe):
184 return self.get_query_set().filter_groupe(groupe)
185
186 def filter_pays(self, pays):
187 return self.get_query_set().filter_pays(pays)
188
189 def filter_nord_sud(self, nord_sud):
190 return self.get_query_set().filter_nord_sud(nord_sud)
191
192 def filter_genre(self, genre):
193 return self.get_query_set().filter_genre(genre=genre)
194
195 def filter_statut(self, statut):
196 return self.get_query_set().filter_statut(statut)
197
198 def filter_expert(self):
199 return self.get_query_set().filter_expert()
200
201 def filter_date_modification(self, min=None, max=None):
202 return self.get_query_set().filter_date_modification(min=min, max=max)
203
204 def order_by_nom(self, direction=''):
205 return self.get_query_set().order_by_nom(self, direction=direction)
206
207 def order_by_etablissement(self, direction=''):
208 return self.get_query_set().order_by_etablissement(self, direction=direction)
209
210 def order_by_pays(self, direction=''):
211 return self.get_query_set().order_by_pays(self, direction=direction)
212
213 STATUT_CHOICES = (
214 ('enseignant', 'Enseignant-chercheur dans un établissement'),
215 ('etudiant', 'Étudiant-chercheur doctorant'),
216 ('independant', 'Chercheur indépendant docteur')
217 )
218
219 class Chercheur(Personne):
220 RESEAU_INSTITUTIONNEL_CHOICES = (
221 ('AFELSH', 'Association des facultés ou établissements de lettres et sciences humaines des universités d’expression française (AFELSH)'),
222 ('CIDEGEF', 'Conférence internationale des dirigeants des institutions d’enseignement supérieur et de recherche de gestion d’expression française (CIDEGEF)'),
223 ('RIFEFF', 'Réseau international francophone des établissements de formation de formateurs (RIFEFF)'),
224 ('CIDMEF', 'Conférence internationale des doyens des facultés de médecine d’expression française (CIDMEF)'),
225 ('CIDCDF', 'Conférence internationale des doyens des facultés de chirurgie dentaire d’expression totalement ou partiellement française (CIDCDF)'),
226 ('CIFDUF', 'Conférence internationale des facultés de droit ayant en commun l’usage du français (CIFDUF)'),
227 ('CIRUISEF', 'Conférence internationale des responsables des universités et institutions à dominante scientifique et technique d’expression française (CIRUISEF)'),
228 ('Theophraste', 'Réseau Théophraste (Réseau de centres francophones de formation au journalisme)'),
229 ('CIDPHARMEF', 'Conférence internationale des doyens des facultés de pharmacie d’expression française (CIDPHARMEF)'),
230 ('CIDEFA', 'Conférence internationale des directeurs et doyens des établissements supérieurs d’expression française des sciences de l’agriculture et de l’alimentation (CIDEFA)'),
231 ('CITEF', 'Conférence internationale des formations d’ingénieurs et techniciens d’expression française (CITEF)'),
232 ('APERAU', 'Association pour la promotion de l’enseignement et de la recherche en aménagement et urbanisme (APERAU)'),
233 )
234 INSTANCE_AUF_CHOICES = (
235 ('CASSOC', 'Conseil associatif'),
236 ('CA', "Conseil d'administration"),
237 ('CS', 'Conseil scientifique'),
238 ('CRE', "Commission régionale d'experts"),
239 ('CR', 'Conférence des recteurs'),
240 ('CNO', "Conseil national d'orientation")
241 )
242
243 nationalite = models.ForeignKey(Pays, null = True, db_column='nationalite', to_field='code',
244 verbose_name = 'nationalité', related_name='nationalite')
245 statut = models.CharField(max_length=36, choices=STATUT_CHOICES)
246 diplome = models.CharField(max_length=255, null=True, verbose_name = 'diplôme le plus élevé')
247 etablissement = models.ForeignKey(Etablissement, db_column='etablissement', null=True, blank=True)
248 etablissement_autre_nom = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'autre établissement')
249 etablissement_autre_pays = models.ForeignKey(Pays, null = True, blank=True, db_column='etablissement_autre_pays',
250 to_field='code', related_name='etablissement_autre_pays',
251 verbose_name = "pays de l'établissement")
252 attestation = models.BooleanField()
253
254 #Domaine
255 thematique = models.ForeignKey(Thematique, db_column='thematique', blank=True, null=True, verbose_name='thematique')
256 mots_cles = models.CharField(max_length=255, null=True, verbose_name='mots-clés')
257 discipline = models.ForeignKey(Discipline, db_column='discipline', null=True, verbose_name='Discipline')
258 theme_recherche = models.TextField(null=True, blank=True, verbose_name='thèmes de recherche')
259 equipe_recherche = models.CharField(max_length=255, blank=True, verbose_name='équipe de recherche')
260 url_site_web = models.URLField(max_length=255, null=True, blank=True,
261 verbose_name='adresse site Internet', verify_exists=False)
262 url_blog = models.URLField(max_length=255, null=True, blank=True, verbose_name='blog',
263 verify_exists=False)
264 url_reseau_social = models.URLField(
265 max_length=255, null=True, blank=True, verbose_name='Réseau social',
266 verify_exists=False,
267 help_text=u"Vous pouvez indiquer ici l'adresse de votre page personnelle dans votre réseau social préféré (e.g. Facebook, LinkedIn, Twitter, Identica, ...)"
268 )
269
270 groupes = models.ManyToManyField('Groupe', through='AdhesionGroupe', related_name='membres', blank=True, verbose_name='groupes')
271
272 # Activités en francophonie
273 membre_instance_auf = models.NullBooleanField(verbose_name="est ou a déjà été membre d'une instance de l'AUF")
274 membre_instance_auf_nom = models.CharField(max_length=10, blank=True, choices=INSTANCE_AUF_CHOICES, verbose_name="instance")
275 membre_instance_auf_fonction = models.CharField(max_length=255, blank=True, verbose_name="fonction")
276 membre_instance_auf_dates = models.CharField(max_length=255, blank=True, verbose_name="dates")
277 expert_oif = models.NullBooleanField(verbose_name="a été sollicité par l'OIF")
278 expert_oif_details = models.CharField(max_length=255, blank=True, verbose_name="détails")
279 expert_oif_dates = models.CharField(max_length=255, blank=True, verbose_name="dates")
280 membre_association_francophone = models.NullBooleanField(verbose_name="est membre d'une association francophone")
281 membre_association_francophone_details = models.CharField(max_length=255, blank=True, verbose_name="nom de l'association")
282 membre_reseau_institutionnel = models.NullBooleanField(
283 verbose_name="est membre des instances d'un réseau institutionnel de l'AUF"
284 )
285 membre_reseau_institutionnel_nom = models.CharField(
286 max_length=15, choices=RESEAU_INSTITUTIONNEL_CHOICES, blank=True,
287 verbose_name="réseau institutionnel"
288 )
289 membre_reseau_institutionnel_fonction = models.CharField(
290 max_length=255, blank=True, verbose_name="fonction"
291 )
292 membre_reseau_institutionnel_dates = models.CharField(
293 max_length=255, blank=True, verbose_name="dates"
294 )
295
296 # Expertises
297 expertises_auf = models.NullBooleanField(verbose_name="est disposé à réaliser des expertises pour l'AUF")
298
299 #meta
300 date_creation = models.DateField(auto_now_add=True, db_column='date_creation')
301 date_modification = models.DateField(auto_now=True, db_column='date_modification')
302
303 # Manager
304 objects = ChercheurManager()
305 all_objects = models.Manager()
306
307 def __unicode__(self):
308 return u"%s %s" % (self.nom.upper(), self.prenom.title())
309
310 def statut_display(self):
311 for s in STATUT_CHOICES:
312 if self.statut == s[0]:
313 return s[1]
314 return "-"
315
316 @property
317 def etablissement_display(self):
318 return (self.nom_etablissement or '') + (', ' + self.pays.nom if self.pays else '')
319
320 @property
321 def pays(self):
322 return self.etablissement.pays if self.etablissement else self.etablissement_autre_pays
323
324 @property
325 def nom_etablissement(self):
326 return self.etablissement.nom if self.etablissement else self.etablissement_autre_nom
327
328 @property
329 def region(self):
330 return self.pays.region
331
332 @property
333 def domaines_recherche(self):
334 return self.groupes.filter(groupe_chercheur=False)
335
336 @property
337 def groupes_chercheur(self):
338 return self.groupes.filter(groupe_chercheur=True)
339
340 def save(self):
341 """Si on a donné un établissement membre, on laisse tomber l'autre établissement."""
342 if self.etablissement:
343 self.etablissement_autre_nom = None
344 self.etablissement_autre_pays = None
345 super(Chercheur, self).save()
346
347 def activation_token(self):
348 return sha_constructor(settings.SECRET_KEY + unicode(self.id)).hexdigest()[::2]
349
350 def get_absolute_url(self):
351 return url('chercheur', kwargs={'id': self.id})
352
353 class ChercheurVoir(Chercheur):
354
355 class Meta:
356 proxy = True
357 verbose_name = 'chercheur (visualisation)'
358 verbose_name_plural = 'chercheur (visualisation)'
359
360 class Publication(models.Model):
361 chercheur = models.ForeignKey(Chercheur, related_name='publications')
362 auteurs = models.CharField(max_length=255, blank=True, verbose_name='auteur(s)')
363 titre = models.CharField(max_length=255, null=True, blank=True, verbose_name='titre')
364 revue = models.CharField(max_length=255, null=True, blank=True, verbose_name='revue')
365 annee = models.IntegerField(null=True, blank=True, verbose_name='année de publication')
366 editeur = models.CharField(max_length=255, null=True, blank=True, verbose_name='éditeur')
367 lieu_edition = models.CharField(max_length=255, null=True, blank=True, verbose_name="lieu d'édition")
368 nb_pages = models.CharField(max_length=255, null=True, blank=True, verbose_name='nombre de pages')
369 url = models.URLField(max_length=255, null=True, blank=True, verbose_name='lien vers la publication', verify_exists=False)
370 #Migration des publications depuis l'ancien repertoire de chercheurs
371 publication_affichage = models.TextField(verbose_name='publication', null=True, blank=True)
372 actif = models.BooleanField(editable=False)
373
374 def __unicode__(self):
375 return self.titre or '(Aucun)'
376
377 def save(self):
378 if self.publication_affichage and (self.auteurs or self.titre or
379 self.revue or self.annee or
380 self.editeur or self.lieu_edition
381 or self.nb_pages or self.url):
382 self.publication_affichage = ''
383 super(Publication, self).save()
384
385 class These(models.Model):
386 chercheur = models.OneToOneField(Chercheur, primary_key=True)
387 titre = models.CharField(max_length=255, verbose_name='Titre')
388 annee = models.IntegerField(verbose_name='Année de soutenance (réalisée ou prévue)')
389 directeur = models.CharField(max_length=255, verbose_name='Directeur')
390 etablissement = models.CharField(max_length=255, verbose_name='Établissement de soutenance')
391 nb_pages = models.IntegerField(verbose_name='Nombre de pages', blank=True, null=True)
392 url = models.URLField(max_length=255, verbose_name='Lien vers la publication', blank=True, verify_exists=False)
393
394 def __unicode__(self):
395 return self.titre
396
397 class Expertise(models.Model):
398 id = models.AutoField(primary_key=True, db_column='id')
399 chercheur = models.ForeignKey(Chercheur, related_name='expertises')
400 nom = models.CharField(max_length=255, verbose_name = "Objet de l'expertise")
401 date = models.CharField(max_length=255, blank=True)
402 lieu = models.CharField(max_length=255, null=True, blank=True, verbose_name = "Lieu de l'expertise")
403 organisme_demandeur = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'Organisme demandeur')
404 organisme_demandeur_visible = models.BooleanField(verbose_name="Afficher l'organisme demandeur")
405 actif = models.BooleanField(editable = False, db_column='actif')
406
407 def __unicode__(self):
408 return u"%s" % (self.nom)
409
410 class GroupeManager(models.Manager):
411 def search(self, text):
412 return self.get_query_set().filter(nom__icontains=text)
413
414 class GroupeChercheurManager(GroupeManager):
415 def get_query_set(self):
416 return super(GroupeChercheurManager, self).get_query_set().filter(groupe_chercheur=True)
417
418 class DomaineRechercheManager(GroupeManager):
419 def get_query_set(self):
420 return super(DomaineRechercheManager, self).get_query_set().filter(groupe_chercheur=False)
421
422 class Groupe(models.Model):
423 id = models.AutoField(primary_key=True, db_column='id')
424 nom = models.CharField(max_length=255, db_column='nom')
425 url = models.URLField(max_length=255, null=True, blank=True,
426 verbose_name='Site web')
427 liste_diffusion = models.URLField(max_length=255, null=True, blank=True,
428 verbose_name='Liste de diffusion')
429 bulletin = models.URLField(max_length=255, null=True, blank=True,
430 verbose_name='Bulletin')
431 actif = models.BooleanField(editable = False, db_column='actif')
432 groupe_chercheur = models.BooleanField(default=False, editable=False, verbose_name='Groupe de chercheur')
433
434 responsables = models.ManyToManyField(User, related_name='responsable_groupe', verbose_name='gestionnaire de communauté', blank=True)
435
436 recherches = models.ManyToManyField(Search, related_name='recherche_groupe', verbose_name='recherches prédéfinies', blank=True)
437
438 page_accueil = models.TextField(null=True, blank=True)
439
440 objects = GroupeManager()
441 groupe_chercheur_objects = GroupeChercheurManager()
442 domaine_recherche_objects = DomaineRechercheManager()
443
444 class Meta:
445 ordering = ['nom']
446 verbose_name = 'domaine de recherche'
447 verbose_name_plural = 'domaines de recherche'
448
449 def __unicode__(self):
450 return u"%s" % (self.nom)
451
452 def get_absolute_url(self):
453 return url('groupe_retrieve', kwargs={'id': self.id})
454
455 def membres_actif(self):
456 return self.membership.filter(statut="accepte")
457
458
459 class GroupeChercheur(Groupe):
460 objects = GroupeChercheurManager()
461
462 class Meta:
463 proxy = True
464 verbose_name = 'communauté de chercheurs'
465 verbose_name_plural = 'communautés de chercheurs'
466
467 def save(self, *args, **kwargs):
468 self.groupe_chercheur = True
469 super(GroupeChercheur, self).save(*args, **kwargs)
470
471 class DomaineRecherche(Groupe):
472 objects = DomaineRechercheManager()
473
474 class Meta:
475 proxy = True
476 verbose_name = 'domaine de recherche'
477 verbose_name_plural = 'domaines de recherche'
478
479 def save(self, *args, **kwargs):
480 self.groupe_chercheur = False
481 super(DomaineRecherche, self).save(*args, **kwargs)
482
483 CG_STATUT_CHOICES = (
484 ('nouveau', 'Nouveau'),
485 ('refuse', 'Refusé'),
486 ('accepte', 'Accepté'),
487 ('resilie', 'Résilié'),
488 ('exclus', 'Exclus'),
489 )
490
491 class AdhesionCommunauteManager(GroupeManager):
492 def get_query_set(self):
493 return super(AdhesionCommunauteManager, self).get_query_set().filter(groupe__groupe_chercheur=True)
494
495 class AdhesionDomaineRechercheManager(GroupeManager):
496 def get_query_set(self):
497 return super(AdhesionDomaineRechercheManager, self).get_query_set().filter(groupe__groupe_chercheur=False)
498
499 class AdhesionGroupe(models.Model):
500 id = models.AutoField(primary_key=True, db_column='id')
501 chercheur = models.ForeignKey('Chercheur', db_column='chercheur')
502 groupe = models.ForeignKey('Groupe', db_column='groupe', related_name="membership")
503 date_inscription = models.DateField(auto_now_add=True)
504 date_modification = models.DateField(auto_now=True)
505 statut = models.CharField(max_length=100, choices=CG_STATUT_CHOICES, default='nouveau')
506
507 class Meta:
508 verbose_name = 'adhésion aux groupes'
509 verbose_name_plural = 'adhésions aux groupes'
510 ordering = ['chercheur']
511
512 def save(self, *args, **kwargs):
513 if self.pk:
514 old_instance = AdhesionGroupe.objects.get(pk=self.pk)
515 if old_instance.statut=='nouveau' and self.statut=='accepte':
516 from django.template.loader import get_template
517 from django.template import Context
518 from django.core.mail import send_mail
519 from django.conf import settings
520
521 template = get_template('chercheurs/groupe_confirmation.txt')
522 domain = settings.SITE_DOMAIN
523 message = template.render(Context(dict(groupe=self.groupe, domain=domain)))
524 send_mail('Votre inscription à Savoirs en partage', message, None, [self.chercheur.courriel])
525
526 super(AdhesionGroupe, self).save(*args, **kwargs)
527
528 def __unicode__(self):
529 return u"%s - %s" % (self.chercheur, self.groupe)
530
531 class AdhesionCommunaute(AdhesionGroupe):
532 objects = AdhesionCommunauteManager()
533
534 class Meta:
535 proxy = True
536 verbose_name = 'adhésion aux communautés de chercheurs'
537 verbose_name_plural = 'adhésion aux communautés de chercheurs'
538
539 class AdhesionDomaineRecherche(AdhesionGroupe):
540 objects = AdhesionDomaineRechercheManager()
541
542 class Meta:
543 proxy = True
544 verbose_name = 'adhésion aux domaines de recherche'
545 verbose_name_plural = 'adhésion aux domaines de recherche'
546
547 class ChercheurSearch(Search):
548 nom_chercheur = models.CharField(max_length=100, blank=True, verbose_name='nom')
549 domaine = models.ForeignKey(DomaineRecherche, blank=True, null=True, verbose_name='domaine de recherche')
550 equipe_recherche = models.CharField(max_length=100, blank=True, null=True,
551 verbose_name='Équipe de recherche',
552 help_text='ou Laboratoire, ou Groupement inter-universitaire')
553 statut = models.CharField(max_length=100, blank=True, choices=STATUT_CHOICES + (('expert', 'Expert'),))
554 pays = models.ForeignKey(Pays, blank=True, null=True)
555 nord_sud = models.CharField(max_length=4, blank=True, choices=(('Nord', 'Nord'), ('Sud', 'Sud')),
556 verbose_name='Nord/Sud',
557 help_text="Distinction d'ordre géopolitique et économique, non géographique, qui conditionne souvent l'attribution de soutiens par les agences internationales: on entend par Nord les pays développés, par Sud les pays en développement (pays les moins avancés, pays émergents et pays à économies en transition)")
558 activites_francophonie = models.CharField(
559 max_length=25, blank=True, verbose_name='activités en Francophonie',
560 choices=(('instance_auf', "Membre d'une instance de l'AUF"),
561 ('expert_oif', "Sollicité par l'OIF"),
562 ('association_francophone', "Membre d'une association ou d'une société savante francophone"),
563 ('reseau_institutionnel', "Membre des instances d'un réseau institutionnel de l'AUF"))
564 )
565 genre = models.CharField(max_length=1, blank=True, choices=GENRE_CHOICES)
566
567 class Meta:
568 verbose_name = 'recherche de chercheurs'
569 verbose_name_plural = 'recherches de chercheurs'
570
571 def run(self, min_date=None, max_date=None):
572 results = Chercheur.objects
573 if self.q:
574 results = results.search(self.q)
575 if self.nom_chercheur:
576 results = results.add_to_query('@(nom,prenom) ' + self.nom_chercheur)
577 if self.equipe_recherche:
578 results = results.add_to_query('@equipe_recherche ' + self.equipe_recherche)
579 if self.discipline:
580 results = results.filter_discipline(self.discipline)
581 if self.region:
582 results = results.filter_region(self.region)
583 if self.statut:
584 if self.statut == "expert":
585 results = results.filter_expert()
586 else:
587 results = results.filter_statut(self.statut)
588 if self.domaine:
589 results = results.filter_groupe(self.domaine)
590 if self.pays:
591 results = results.filter_pays(self.pays)
592 if self.nord_sud:
593 results = results.filter_nord_sud(self.nord_sud)
594 if self.genre:
595 results = results.filter_genre(self.genre)
596 if self.activites_francophonie == 'instance_auf':
597 results = results.filter(membre_instance_auf=True)
598 elif self.activites_francophonie == 'expert_oif':
599 results = results.filter(expert_oif=True)
600 elif self.activites_francophonie == 'association_francophone':
601 results = results.filter(membre_association_francophone=True)
602 elif self.activites_francophonie == 'reseau_institutionnel':
603 results = results.filter(membre_reseau_institutionnel=True)
604 if min_date:
605 results = results.filter_date_modification(min=min_date)
606 if max_date:
607 results = results.filter_date_modification(max=max_date)
608 return results.all()
609
610 def url(self):
611 qs = self.query_string()
612 return url('chercheurs') + ('?' + qs if qs else '')
613
614 def rss_url(self):
615 qs = self.query_string()
616 return url('rss_chercheurs') + ('?' + qs if qs else '')
617
618 def get_email_alert_content(self, results):
619 content = ''
620 for chercheur in results:
621 content += u'- [%s %s](%s%s) \n' % (chercheur.nom.upper(),
622 chercheur.prenom,
623 settings.SITE_ROOT_URL,
624 chercheur.get_absolute_url())
625 content += u' %s\n\n' % chercheur.etablissement_display
626 return content
627
628 class GroupeSearch(Search):
629
630 class Meta:
631 verbose_name = 'recherche de groupe'
632 verbose_name_plural = 'recherches de groupes'
633
634 def run(self):
635 results = Groupe.groupe_chercheur_objects
636 if self.q:
637 results = results.search(self.q)
638 return results.all()
639
640 #def url(self):
641 # qs = self.query_string()
642 # return url('groupes') + ('?' + qs if qs else '')
643
644 #def rss_url(self):
645 # qs = self.query_string()
646 # return url('rss_groupes') + ('?' + qs if qs else '')
647
648 class Message(models.Model):
649
650 chercheur = models.ForeignKey('Chercheur', db_column='chercheur')
651 groupe = models.ForeignKey('Groupe', db_column='groupe')
652 titre = models.CharField(max_length=255)
653 contenu = models.TextField()
654
655 date_creation = models.DateTimeField(auto_now_add=True, db_column='date_creation')
656
657 class Meta:
658 ordering = ['-date_creation']
659
660 def __unicode__(self):
661 return u"%s - %s" % (self.chercheur, self.titre)
662
663 def get_absolute_url(self):
664 return url('groupe_messages', kwargs={'id': self.groupe.id})
665
666
667 class AuthLDAP(models.Model):
668 username = models.CharField('utilisateur', max_length=255, unique=True)
669 ldap_hash = models.CharField('hash LDAP', max_length=255)
670 date_modification = models.DateTimeField(auto_now=True)
671
672 def __unicode__(self):
673 return self.username