Groupe(s) de chercheur -> groupe(s) de chercheurs, pour les verbose_name
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / models.py
CommitLineData
932eef9a 1# -*- encoding: utf-8 -*-
92990258 2import hashlib
fdcf5874 3
5212238e 4from datamaster_modeles.models import *
43ed73e7 5from django.conf import settings
fdcf5874
EMS
6from django.contrib.auth.models import User
7from django.core.urlresolvers import reverse as url
932eef9a 8from django.db import models
a2c6bb72 9from django.db.models import Q
92990258 10from django.utils.encoding import smart_str
43ed73e7 11from django.utils.hashcompat import sha_constructor
5212238e 12from djangosphinx.models import SphinxSearch
fdcf5874
EMS
13
14from savoirs.models import Discipline, SEPManager, SEPSphinxQuerySet, SEPQuerySet, Search
932eef9a 15
13146d99 16GENRE_CHOICES = (('m', 'Homme'), ('f', 'Femme'))
932eef9a 17class Personne(models.Model):
595ab4d6 18 salutation = models.CharField(max_length=128, null=True, blank=True)
932eef9a 19 nom = models.CharField(max_length=255)
595ab4d6 20 prenom = models.CharField(max_length=128, verbose_name='prénom')
165da916
EMS
21 courriel = models.EmailField(max_length=128, verbose_name="courriel")
22 afficher_courriel = models.BooleanField(default=True)
595ab4d6 23 fonction = models.CharField(max_length=128, null=True, blank=True)
c18af6bd 24 date_naissance = models.DateField(null=True, blank=True)
595ab4d6 25 sousfonction = models.CharField(max_length=128, null=True, blank=True, verbose_name='sous-fonction')
0a379c77
EMS
26 telephone = models.CharField(max_length=32, null=True, blank=True, verbose_name='numéro de téléphone')
27 adresse_postale = models.TextField(blank=True)
932eef9a 28 genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
595ab4d6 29 commentaire = models.TextField(verbose_name='commentaires', null=True, blank=True)
3e556e66 30 actif = models.BooleanField(editable=False, default=False)
932eef9a
AJ
31
32 def __unicode__(self):
33 return u"%s %s, %s" % (self.prenom, self.nom, self.courriel)
34
35 class Meta:
13ec4813 36 ordering = ["nom", "prenom"]
92990258 37
705013cb
EMS
38 @property
39 def civilite(self):
40 if self.genre == 'm':
41 return 'M.'
42 elif self.genre == 'f':
43 return 'Mme'
44 else:
45 return ''
46
3a3d9c6f
EMS
47 def courriel_display(self):
48 return self.courriel.replace(u'@', u' (à) ')
49
5212238e 50class ChercheurQuerySet(SEPQuerySet):
a2c6bb72 51
5212238e
EMS
52 def filter_groupe(self, groupe):
53 return self.filter(groupes=groupe)
54
55 def filter_pays(self, pays):
56 return self.filter(Q(etablissement__pays=pays) | Q(etablissement_autre_pays=pays))
57
58 def filter_region(self, region):
59 return self.filter(Q(etablissement__pays__region=region) | Q(etablissement_autre_pays__region=region))
a2c6bb72 60
5212238e
EMS
61 def filter_nord_sud(self, nord_sud):
62 return self.filter(Q(etablissement__pays__nord_sud=nord_sud) | Q(etablissement_autre_pays__nord_sud=nord_sud))
116db1fd 63
5c9bae2d
OL
64 def filter_genre(self, genre):
65 return self.filter(genre=genre)
66
5212238e
EMS
67 def filter_statut(self, statut):
68 return self.filter(statut=statut)
69
70 def filter_expert(self):
71 return self.exclude(expertises=None)
72
230671ff
EMS
73 def filter_date_modification(self, min=None, max=None):
74 return self._filter_date('date_modification', min=min, max=max)
75
acd5cd8f 76 def order_by_nom(self, direction=''):
3648b3d6 77 return self.order_by(direction + 'nom', direction + 'prenom', '-date_modification')
acd5cd8f
EMS
78
79 def order_by_etablissement(self, direction=''):
1760a3e9
EMS
80 return self.extra(select=dict(etablissement_nom='IFNULL(ref_etablissement.nom, chercheurs_chercheur.etablissement_autre_nom)'),
81 order_by=[direction + 'etablissement_nom', '-date_modification'])
acd5cd8f
EMS
82
83 def order_by_pays(self, direction=''):
84 return self.extra(select=dict(
85 pays_etablissement='''(SELECT nom FROM ref_pays
86 WHERE ref_pays.code = IFNULL(ref_etablissement.pays, chercheurs_chercheur.etablissement_autre_pays))'''
87 ), order_by=[direction + 'pays_etablissement', '-date_modification'])
88
5212238e
EMS
89class ChercheurSphinxQuerySet(SEPSphinxQuerySet):
90
91 def __init__(self, model=None):
4134daa0 92 return SEPSphinxQuerySet.__init__(self, model=model, index='savoirsenpartage_chercheurs',
acd5cd8f 93 weights=dict(nom=2, prenom=2))
d9da735f 94
c1b134f8 95 def filter_region(self, region):
5212238e
EMS
96 return self.filter(region_id=region.id)
97
98 def filter_groupe(self, groupe):
99 return self.filter(groupe_ids=groupe.id)
100
101 def filter_pays(self, pays):
102 return self.filter(pays_id=pays.id)
c1b134f8 103
5212238e
EMS
104 NORD_SUD_CODES = {'Nord': 1, 'Sud': 2}
105 def filter_nord_sud(self, nord_sud):
106 return self.filter(nord_sud=self.NORD_SUD_CODES[nord_sud])
107
c6efde25
OL
108 GENRE_CODES = dict([(k, i+1) for i, (k, v) in enumerate(GENRE_CHOICES)])
109 def filter_genre(self, genre):
110 return self.filter(genre=self.GENRE_CODES[genre])
111
5212238e
EMS
112 STATUT_CODES = {'enseignant': 1, 'etudiant': 2, 'independant': 3}
113 def filter_statut(self, statut):
114 return self.filter(statut=self.STATUT_CODES[statut])
115
d9da735f
EMS
116 def filter_expert(self):
117 return self.filter(expert=True)
118
230671ff 119 def filter_date_modification(self, min=None, max=None):
7ed3ee8f 120 return self._filter_date('date_modification', min=min, max=max)
230671ff 121
acd5cd8f
EMS
122 def order_by_nom(self, direction=''):
123 return self.order_by(direction + 'nom_complet', '-date_modification')
124
125 def order_by_etablissement(self, direction=''):
126 return self.order_by(direction + 'etablissement_attr', '-date_modification')
127
128 def order_by_pays(self, direction=''):
129 return self.order_by(direction + 'pays_attr', '-date_modification')
130
5212238e 131class ChercheurManager(SEPManager):
a2c6bb72
EMS
132
133 def get_query_set(self):
695930dd 134 return ChercheurQuerySet(self.model).filter(actif=True)
a2c6bb72 135
5212238e
EMS
136 def get_sphinx_query_set(self):
137 return ChercheurSphinxQuerySet(self.model).order_by('-date_modification')
5212238e 138
116db1fd 139 def filter_region(self, region):
5212238e 140 """Le filtrage de chercheurs par région n'est pas une recherche texte."""
c1b134f8
EMS
141 return self.get_query_set().filter_region(region)
142
5212238e
EMS
143 def filter_groupe(self, groupe):
144 return self.get_query_set().filter_groupe(groupe)
bae03b7b 145
5212238e
EMS
146 def filter_pays(self, pays):
147 return self.get_query_set().filter_pays(pays)
148
149 def filter_nord_sud(self, nord_sud):
150 return self.get_query_set().filter_nord_sud(nord_sud)
151
a7bf6c5a 152 def filter_genre(self, genre):
634d46da 153 return self.get_query_set().filter_genre(genre=genre)
a7bf6c5a 154
5212238e
EMS
155 def filter_statut(self, statut):
156 return self.get_query_set().filter_statut(statut)
157
158 def filter_expert(self):
159 return self.get_query_set().filter_expert()
3efbacbe 160
230671ff
EMS
161 def filter_date_modification(self, min=None, max=None):
162 return self.get_query_set().filter_date_modification(min=min, max=max)
163
acd5cd8f
EMS
164 def order_by_nom(self, direction=''):
165 return self.get_query_set().order_by_nom(self, direction=direction)
166
167 def order_by_etablissement(self, direction=''):
168 return self.get_query_set().order_by_etablissement(self, direction=direction)
169
170 def order_by_pays(self, direction=''):
171 return self.get_query_set().order_by_pays(self, direction=direction)
172
bc15119b
EMS
173STATUT_CHOICES = (
174 ('enseignant', 'Enseignant-chercheur dans un établissement'),
175 ('etudiant', 'Étudiant-chercheur doctorant'),
176 ('independant', 'Chercheur indépendant docteur')
177)
178
13ec4813 179class Chercheur(Personne):
bc15119b
EMS
180 RESEAU_INSTITUTIONNEL_CHOICES = (
181 ('AFELSH', 'Association des facultés ou établissements de lettres et sciences humaines des universités d’expression française (AFELSH)'),
182 ('CIDEGEF', 'Conférence internationale des dirigeants des institutions d’enseignement supérieur et de recherche de gestion d’expression française (CIDEGEF)'),
183 ('RIFEFF', 'Réseau international francophone des établissements de formation de formateurs (RIFEFF)'),
184 ('CIDMEF', 'Conférence internationale des doyens des facultés de médecine d’expression française (CIDMEF)'),
185 ('CIDCDF', 'Conférence internationale des doyens des facultés de chirurgie dentaire d’expression totalement ou partiellement française (CIDCDF)'),
186 ('CIFDUF', 'Conférence internationale des facultés de droit ayant en commun l’usage du français (CIFDUF)'),
187 ('CIRUISEF', 'Conférence internationale des responsables des universités et institutions à dominante scientifique et technique d’expression française (CIRUISEF)'),
188 ('Theophraste', 'Réseau Théophraste (Réseau de centres francophones de formation au journalisme)'),
189 ('CIDPHARMEF', 'Conférence internationale des doyens des facultés de pharmacie d’expression française (CIDPHARMEF)'),
190 ('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)'),
191 ('CITEF', 'Conférence internationale des formations d’ingénieurs et techniciens d’expression française (CITEF)'),
192 ('APERAU', 'Association pour la promotion de l’enseignement et de la recherche en aménagement et urbanisme (APERAU)'),
193 )
194 INSTANCE_AUF_CHOICES = (
195 ('CASSOC', 'Conseil associatif'),
196 ('CA', "Conseil d'administration"),
197 ('CS', 'Conseil scientifique'),
2fcf82c9
EMS
198 ('CRE', "Commission régionale d'experts"),
199 ('CR', 'Conférence des recteurs'),
200 ('CNO', "Conseil national d'orientation")
bc15119b
EMS
201 )
202
00755d9b 203 nationalite = models.ForeignKey(Pays, null = True, db_column='nationalite', to_field='code',
0b0fbbd7 204 verbose_name = 'nationalité', related_name='nationalite')
a4e383ac 205 statut = models.CharField(max_length=36, choices=STATUT_CHOICES)
0b0fbbd7 206 diplome = models.CharField(max_length=255, null=True, verbose_name = 'diplôme le plus élevé')
73cabd75 207 etablissement = models.ForeignKey(Etablissement, db_column='etablissement', null=True, blank=True)
0b0fbbd7 208 etablissement_autre_nom = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'autre établissement')
00755d9b 209 etablissement_autre_pays = models.ForeignKey(Pays, null = True, blank=True, db_column='etablissement_autre_pays',
0b0fbbd7
EMS
210 to_field='code', related_name='etablissement_autre_pays',
211 verbose_name = "pays de l'établissement")
0874e7d1 212 attestation = models.BooleanField()
73cabd75 213
0b0fbbd7 214 #Domaine
602e4194 215 thematique = models.ForeignKey(Thematique, db_column='thematique', blank=True, null=True, verbose_name='thematique')
518d0b44 216 mots_cles = models.CharField(max_length=255, null=True, verbose_name='mots-clés')
0b0fbbd7 217 discipline = models.ForeignKey(Discipline, db_column='discipline', null=True, verbose_name='Discipline')
518d0b44 218 theme_recherche = models.TextField(null=True, blank=True, verbose_name='thèmes de recherche')
0b0fbbd7 219 groupe_recherche = models.CharField(max_length=255, blank=True, verbose_name='groupe de recherche')
219710da
EMS
220 url_site_web = models.URLField(max_length=255, null=True, blank=True,
221 verbose_name='adresse site Internet', verify_exists=False)
222 url_blog = models.URLField(max_length=255, null=True, blank=True, verbose_name='blog',
223 verify_exists=False)
3c576696
EMS
224 url_reseau_social = models.URLField(
225 max_length=255, null=True, blank=True, verbose_name='Réseau social',
219710da 226 verify_exists=False,
3c576696
EMS
227 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, ...)"
228 )
00755d9b 229
0c0d997c 230 groupes = models.ManyToManyField('Groupe', through='ChercheurGroupe', related_name='membres', blank=True, verbose_name='Domaines de recherche')
932eef9a 231
a7b16ec9 232 # Activités en francophonie
121d9439 233 membre_instance_auf = models.NullBooleanField(verbose_name="est ou a déjà été membre d'une instance de l'AUF")
bc15119b
EMS
234 membre_instance_auf_nom = models.CharField(max_length=10, blank=True, choices=INSTANCE_AUF_CHOICES, verbose_name="instance")
235 membre_instance_auf_fonction = models.CharField(max_length=255, blank=True, verbose_name="fonction")
a7b16ec9 236 membre_instance_auf_dates = models.CharField(max_length=255, blank=True, verbose_name="dates")
121d9439 237 expert_oif = models.NullBooleanField(verbose_name="a été sollicité par l'OIF")
614b3269
EMS
238 expert_oif_details = models.CharField(max_length=255, blank=True, verbose_name="détails")
239 expert_oif_dates = models.CharField(max_length=255, blank=True, verbose_name="dates")
121d9439 240 membre_association_francophone = models.NullBooleanField(verbose_name="est membre d'une association francophone")
c073c94d 241 membre_association_francophone_details = models.CharField(max_length=255, blank=True, verbose_name="nom de l'association")
121d9439
EMS
242 membre_reseau_institutionnel = models.NullBooleanField(
243 verbose_name="est membre des instances d'un réseau institutionnel de l'AUF"
bc15119b
EMS
244 )
245 membre_reseau_institutionnel_nom = models.CharField(
246 max_length=15, choices=RESEAU_INSTITUTIONNEL_CHOICES, blank=True,
247 verbose_name="réseau institutionnel"
c073c94d 248 )
bc15119b
EMS
249 membre_reseau_institutionnel_fonction = models.CharField(
250 max_length=255, blank=True, verbose_name="fonction"
c073c94d
EMS
251 )
252 membre_reseau_institutionnel_dates = models.CharField(
253 max_length=255, blank=True, verbose_name="dates"
254 )
a7b16ec9 255
cb591fb3 256 # Expertises
121d9439 257 expertises_auf = models.NullBooleanField(verbose_name="est disposé à réaliser des expertises pour l'AUF")
cb591fb3 258
00755d9b
AJ
259 #meta
260 date_creation = models.DateField(auto_now_add=True, db_column='date_creation')
261 date_modification = models.DateField(auto_now=True, db_column='date_modification')
262
a2c6bb72
EMS
263 # Manager
264 objects = ChercheurManager()
c59dba82 265 all_objects = models.Manager()
a2c6bb72 266
588d6b93 267 def __unicode__(self):
13ec4813 268 return u"%s %s" % (self.nom.upper(), self.prenom.title())
e427f068 269
b57a7362
AJ
270 def statut_display(self):
271 for s in STATUT_CHOICES:
272 if self.statut == s[0]:
273 return s[1]
e427f068 274 return "-"
588d6b93 275
e4d01d1d
EMS
276 @property
277 def etablissement_display(self):
230671ff 278 return (self.nom_etablissement or '') + (', ' + self.pays.nom if self.pays else '')
e4d01d1d 279
d32102bd
EMS
280 @property
281 def pays(self):
282 return self.etablissement.pays if self.etablissement else self.etablissement_autre_pays
283
284 @property
d264c787
EMS
285 def nom_etablissement(self):
286 return self.etablissement.nom if self.etablissement else self.etablissement_autre_nom
287
288 @property
d32102bd
EMS
289 def region(self):
290 return self.pays.region
291
5b55252d
PP
292 @property
293 def domaines_recherche(self):
294 return self.groupes.filter(groupe_chercheur=False)
295
296 @property
297 def groupes_chercheur(self):
298 return self.groupes.filter(groupe_chercheur=True)
299
71e3d741
EMS
300 def save(self):
301 """Si on a donné un établissement membre, on laisse tomber l'autre établissement."""
302 if self.etablissement:
303 self.etablissement_autre_nom = None
304 self.etablissement_autre_pays = None
305 super(Chercheur, self).save()
306
43ed73e7
EMS
307 def activation_token(self):
308 return sha_constructor(settings.SECRET_KEY + unicode(self.id)).hexdigest()[::2]
309
4b89a7df
EMS
310 def get_absolute_url(self):
311 return url('chercheur', kwargs={'id': self.id})
312
81fe476e
PP
313class ChercheurVoir(Chercheur):
314
315 class Meta:
316 proxy = True
317 verbose_name = '(visualisation) chercheur'
318 verbose_name_plural = '(visualisation) chercheur'
319
00755d9b 320class Publication(models.Model):
595ab4d6 321 chercheur = models.ForeignKey(Chercheur, related_name='publications')
1df3737b 322 auteurs = models.CharField(max_length=255, blank=True, verbose_name='auteur(s)')
595ab4d6 323 titre = models.CharField(max_length=255, null=True, blank=True, verbose_name='titre')
1df3737b
EMS
324 revue = models.CharField(max_length=255, null=True, blank=True, verbose_name='revue')
325 annee = models.IntegerField(null=True, blank=True, verbose_name='année de publication')
326 editeur = models.CharField(max_length=255, null=True, blank=True, verbose_name='éditeur')
327 lieu_edition = models.CharField(max_length=255, null=True, blank=True, verbose_name="lieu d'édition")
328 nb_pages = models.CharField(max_length=255, null=True, blank=True, verbose_name='nombre de pages')
912e3c6c 329 url = models.URLField(max_length=255, null=True, blank=True, verbose_name='lien vers la publication', verify_exists=False)
6befc7c9 330 #Migration des publications depuis l'ancien repertoire de chercheurs
1df3737b 331 publication_affichage = models.TextField(verbose_name='publication', null=True, blank=True)
595ab4d6 332 actif = models.BooleanField(editable=False)
2a36714f
AJ
333
334 def __unicode__(self):
c59dba82 335 return self.titre or '(Aucun)'
2a36714f 336
3eb41a6d
EMS
337 def save(self):
338 if self.publication_affichage and (self.auteurs or self.titre or
339 self.revue or self.annee or
340 self.editeur or self.lieu_edition
341 or self.nb_pages or self.url):
342 self.publication_affichage = ''
343 super(Publication, self).save()
344
595ab4d6
EMS
345class These(models.Model):
346 chercheur = models.OneToOneField(Chercheur, primary_key=True)
14fd1c3f 347 titre = models.CharField(max_length=255, verbose_name='Titre')
595ab4d6 348 annee = models.IntegerField(verbose_name='Année de soutenance (réalisée ou prévue)')
14fd1c3f 349 directeur = models.CharField(max_length=255, verbose_name='Directeur')
595ab4d6
EMS
350 etablissement = models.CharField(max_length=255, verbose_name='Établissement de soutenance')
351 nb_pages = models.IntegerField(verbose_name='Nombre de pages', blank=True, null=True)
912e3c6c 352 url = models.URLField(max_length=255, verbose_name='Lien vers la publication', blank=True, verify_exists=False)
595ab4d6
EMS
353
354 def __unicode__(self):
355 return self.titre
356
2a36714f
AJ
357class Expertise(models.Model):
358 id = models.AutoField(primary_key=True, db_column='id')
ee8b3a49 359 chercheur = models.ForeignKey(Chercheur, related_name='expertises')
356cc691 360 nom = models.CharField(max_length=255, verbose_name = "Objet de l'expertise")
c1234eb8 361 date = models.CharField(max_length=255, blank=True)
ee8b3a49 362 lieu = models.CharField(max_length=255, null=True, blank=True, verbose_name = "Lieu de l'expertise")
b16bcbaf
EMS
363 organisme_demandeur = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'Organisme demandeur')
364 organisme_demandeur_visible = models.BooleanField(verbose_name="Afficher l'organisme demandeur")
2a36714f 365 actif = models.BooleanField(editable = False, db_column='actif')
5b9abc81
AJ
366
367 def __unicode__(self):
368 return u"%s" % (self.nom)
2a36714f 369
057c3327
PP
370class GroupeManager(models.Manager):
371 def search(self, text):
372 return self.get_query_set().filter(nom__icontains=text)
373
374class GroupeChercheurManager(GroupeManager):
5b55252d
PP
375 def get_query_set(self):
376 return super(GroupeChercheurManager, self).get_query_set().filter(groupe_chercheur=True)
377
057c3327 378class DomaineRechercheManager(GroupeManager):
5b55252d
PP
379 def get_query_set(self):
380 return super(DomaineRechercheManager, self).get_query_set().filter(groupe_chercheur=False)
381
932eef9a
AJ
382class Groupe(models.Model):
383 id = models.AutoField(primary_key=True, db_column='id')
384 nom = models.CharField(max_length=255, db_column='nom')
00755d9b
AJ
385 url = models.URLField(max_length=255, null=True, blank=True,
386 verbose_name='Site web')
387 liste_diffusion = models.URLField(max_length=255, null=True, blank=True,
388 verbose_name='Liste de diffusion')
389 bulletin = models.URLField(max_length=255, null=True, blank=True,
390 verbose_name='Bulletin')
932eef9a 391 actif = models.BooleanField(editable = False, db_column='actif')
04985abd 392 groupe_chercheur = models.BooleanField(default=False, editable=False, verbose_name='Groupe de chercheur')
5b55252d 393
4a7399ee 394 responsables = models.ManyToManyField(User, related_name='responsable_groupe', verbose_name='responsables', blank=True)
cec3f8db 395
2094c7e5
PP
396 recherches = models.ManyToManyField(Search, related_name='recherche_groupe', verbose_name='recherches prédéfinies', blank=True)
397
0c0d997c 398 page_accueil = models.TextField(null=True, blank=True)
5b55252d 399
057c3327 400 objects = GroupeManager()
5b55252d
PP
401 groupe_chercheur_objects = GroupeChercheurManager()
402 domaine_recherche_objects = DomaineRechercheManager()
932eef9a 403
55ef8558
EMS
404 class Meta:
405 verbose_name = 'domaine de recherche'
406 verbose_name_plural = 'domaines de recherche'
407
932eef9a
AJ
408 def __unicode__(self):
409 return u"%s" % (self.nom)
5b55252d 410
bf2904f0
PP
411 def get_absolute_url(self):
412 return url('groupe_retrieve', kwargs={'id': self.id})
413
414
5b55252d
PP
415class GroupeChercheur(Groupe):
416 objects = GroupeChercheurManager()
417
418 class Meta:
419 proxy = True
575aab27
PP
420 verbose_name = 'groupe de chercheurs'
421 verbose_name_plural = 'groupes de chercheurs'
5b55252d 422
04985abd
PP
423 def save(self, *args, **kwargs):
424 self.groupe_chercheur = True
425 super(GroupeChercheur, self).save(*args, **kwargs)
426
5b55252d
PP
427class DomaineRecherche(Groupe):
428 objects = DomaineRechercheManager()
429
430 class Meta:
431 proxy = True
432 verbose_name = 'domaine de recherche'
433 verbose_name_plural = 'domaines de recherche'
434
04985abd
PP
435 def save(self, *args, **kwargs):
436 self.groupe_chercheur = False
437 super(DomaineRecherche, self).save(*args, **kwargs)
438
932eef9a 439class ChercheurGroupe(models.Model):
73cabd75 440 id = models.AutoField(primary_key=True, db_column='id')
6d5279ff 441 chercheur = models.ForeignKey('Chercheur', db_column='chercheur')
0c0d997c 442 groupe = models.ForeignKey('Groupe', db_column='groupe', related_name="membership")
00755d9b
AJ
443 date_inscription = models.DateField(auto_now_add=True)
444 date_modification = models.DateField(auto_now=True)
6d5279ff 445 actif = models.BooleanField(db_column='actif')
2a36714f 446
55ef8558
EMS
447 class Meta:
448 verbose_name = 'adhésion'
449
2a36714f
AJ
450 def __unicode__(self):
451 return u"%s - %s" % (self.chercheur, self.groupe)
fdcf5874
EMS
452
453class ChercheurSearch(Search):
454 nom_chercheur = models.CharField(max_length=100, blank=True, verbose_name='nom')
5b55252d 455 domaine = models.ForeignKey(DomaineRecherche, blank=True, null=True, verbose_name='domaine de recherche')
e98697a2 456 groupe_chercheur = models.ForeignKey(GroupeChercheur, blank=True, null=True, verbose_name='groupe de chercheurs')
fdcf5874
EMS
457 groupe_recherche = models.CharField(max_length=100, blank=True, null=True,
458 verbose_name='groupe de recherche',
459 help_text='ou Laboratoire, ou Groupement inter-universitaire')
460 statut = models.CharField(max_length=100, blank=True, choices=STATUT_CHOICES + (('expert', 'Expert'),))
461 pays = models.ForeignKey(Pays, blank=True, null=True)
462 nord_sud = models.CharField(max_length=4, blank=True, choices=(('Nord', 'Nord'), ('Sud', 'Sud')),
463 verbose_name='Nord/Sud',
464 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)")
465 activites_francophonie = models.CharField(
466 max_length=25, blank=True, verbose_name='activités en Francophonie',
467 choices=(('instance_auf', "Membre d'une instance de l'AUF"),
468 ('expert_oif', "Sollicité par l'OIF"),
469 ('association_francophone', "Membre d'une association ou d'une société savante francophone"),
470 ('reseau_institutionnel', "Membre des instances d'un réseau institutionnel de l'AUF"))
471 )
472 genre = models.CharField(max_length=1, blank=True, choices=GENRE_CHOICES)
473
474 class Meta:
475 verbose_name = 'recherche de chercheurs'
476 verbose_name_plural = 'recherches de chercheurs'
477
4b89a7df 478 def run(self, min_date=None, max_date=None):
fdcf5874
EMS
479 results = Chercheur.objects
480 if self.q:
481 results = results.search(self.q)
482 if self.nom_chercheur:
483 results = results.add_to_query('@(nom,prenom) ' + self.nom_chercheur)
484 if self.groupe_recherche:
485 results = results.add_to_query('@groupe_recherche ' + self.groupe_recherche)
486 if self.discipline:
487 results = results.filter_discipline(self.discipline)
488 if self.region:
489 results = results.filter_region(self.region)
490 if self.statut:
491 if self.statut == "expert":
492 results = results.filter_expert()
493 else:
494 results = results.filter_statut(self.statut)
495 if self.domaine:
496 results = results.filter_groupe(self.domaine)
5b55252d
PP
497 if self.groupe_chercheur:
498 results = results.filter_groupe(self.groupe_chercheur)
fdcf5874
EMS
499 if self.pays:
500 results = results.filter_pays(self.pays)
501 if self.nord_sud:
502 results = results.filter_nord_sud(self.nord_sud)
503 if self.genre:
504 results = results.filter_genre(self.genre)
505 if self.activites_francophonie == 'instance_auf':
506 results = results.filter(membre_instance_auf=True)
507 elif self.activites_francophonie == 'expert_oif':
508 results = results.filter(expert_oif=True)
509 elif self.activites_francophonie == 'association_francophone':
510 results = results.filter(membre_association_francophone=True)
511 elif self.activites_francophonie == 'reseau_institutionnel':
512 results = results.filter(membre_reseau_institutionnel=True)
4b89a7df
EMS
513 if min_date:
514 results = results.filter_date_modification(min=min_date)
515 if max_date:
516 results = results.filter_date_modification(max=max_date)
fdcf5874
EMS
517 return results.all()
518
519 def url(self):
520 qs = self.query_string()
521 return url('chercheurs') + ('?' + qs if qs else '')
da5bf7e9
EMS
522
523 def rss_url(self):
524 qs = self.query_string()
525 return url('rss_chercheurs') + ('?' + qs if qs else '')
4b89a7df
EMS
526
527 def get_email_alert_content(self, results):
528 content = ''
529 for chercheur in results:
530 content += u'- [%s %s](%s%s) \n' % (chercheur.nom.upper(),
531 chercheur.prenom,
532 settings.SITE_ROOT_URL,
533 chercheur.get_absolute_url())
534 content += u' %s\n\n' % chercheur.etablissement_display
535 return content
cdaadee3
PP
536
537class GroupeSearch(Search):
538
539 class Meta:
540 verbose_name = 'recherche de groupe'
541 verbose_name_plural = 'recherches de groupes'
542
543 def run(self):
544 results = Groupe.objects
545 if self.q:
546 results = results.search(self.q)
547 return results.all()
548
549 #def url(self):
550 # qs = self.query_string()
551 # return url('groupes') + ('?' + qs if qs else '')
552
553 #def rss_url(self):
554 # qs = self.query_string()
555 # return url('rss_groupes') + ('?' + qs if qs else '')
2048049e
PP
556
557class Message(models.Model):
558
559 chercheur = models.ForeignKey('Chercheur', db_column='chercheur')
560 groupe = models.ForeignKey('Groupe', db_column='groupe')
561 titre = models.CharField(max_length=255)
562 contenu = models.TextField()
563
fd6352ea 564 date_creation = models.DateTimeField(auto_now_add=True, db_column='date_creation')
2048049e 565
bf2904f0
PP
566 class Meta:
567 ordering = ['-date_creation']
568
2048049e
PP
569 def __unicode__(self):
570 return u"%s - %s" % (self.chercheur, self.titre)
c8d6b979 571
bf2904f0
PP
572 def get_absolute_url(self):
573 return url('groupe_messages', kwargs={'id': self.groupe.id})
574