1 # -*- encoding: utf-8 -*-
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 djangosphinx
.models
import SphinxSearch
14 from savoirs
.models
import Discipline
, SEPManager
, SEPSphinxQuerySet
, SEPQuerySet
, Search
16 GENRE_CHOICES
= (('m', 'Homme'), ('f', 'Femme'))
17 class Personne(models
.Model
):
18 salutation
= models
.CharField(max_length
=128, null
=True, blank
=True)
19 nom
= models
.CharField(max_length
=255)
20 prenom
= models
.CharField(max_length
=128, verbose_name
='prénom')
21 courriel
= models
.EmailField(max_length
=128, verbose_name
="courriel")
22 afficher_courriel
= models
.BooleanField(default
=True)
23 fonction
= models
.CharField(max_length
=128, null
=True, blank
=True)
24 date_naissance
= models
.DateField(null
=True, blank
=True)
25 sousfonction
= models
.CharField(max_length
=128, null
=True, blank
=True, verbose_name
='sous-fonction')
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)
28 genre
= models
.CharField(max_length
=1, choices
=GENRE_CHOICES
)
29 commentaire
= models
.TextField(verbose_name
='commentaires', null
=True, blank
=True)
30 actif
= models
.BooleanField(editable
=False, default
=False)
32 def __unicode__(self
):
33 return u
"%s %s, %s" % (self
.prenom
, self
.nom
, self
.courriel
)
36 ordering
= ["nom", "prenom"]
38 def save(self
, *args
, **kwargs
):
41 old_instance
= Personne
.objects
.get(pk
=self
.pk
)
42 if self
.courriel
!= old_instance
.courriel
:
44 user
= User
.objects
.get(email
=old_instance
.courriel
)
45 user
.email
= self
.courriel
47 except User
.DoesNotExist
:
49 except Personne
.DoesNotExist
:
52 super(Personne
, self
).save(*args
, **kwargs
)
58 elif self
.genre
== 'f':
63 def courriel_display(self
):
64 return self
.courriel
.replace(u
'@', u
' (à) ')
66 class ChercheurQuerySet(SEPQuerySet
):
68 def filter_groupe(self
, groupe
):
69 return self
.filter(groupes
=groupe
)
71 def filter_pays(self
, pays
):
72 return self
.filter(Q(etablissement__pays
=pays
) |
Q(etablissement_autre_pays
=pays
))
74 def filter_region(self
, region
):
75 return self
.filter(Q(etablissement__pays__region
=region
) |
Q(etablissement_autre_pays__region
=region
))
77 def filter_nord_sud(self
, nord_sud
):
78 return self
.filter(Q(etablissement__pays__nord_sud
=nord_sud
) |
Q(etablissement_autre_pays__nord_sud
=nord_sud
))
80 def filter_genre(self
, genre
):
81 return self
.filter(genre
=genre
)
83 def filter_statut(self
, statut
):
84 return self
.filter(statut
=statut
)
86 def filter_expert(self
):
87 return self
.exclude(expertises
=None)
89 def filter_date_modification(self
, min=None, max=None):
90 return self
._filter_date('date_modification', min=min, max=max)
92 def order_by_nom(self
, direction
=''):
93 return self
.order_by(direction
+ 'nom', direction
+ 'prenom', '-date_modification')
95 def order_by_etablissement(self
, direction
=''):
96 return self
.extra(select
=dict(etablissement_nom
='IFNULL(ref_etablissement.nom, chercheurs_chercheur.etablissement_autre_nom)'),
97 order_by
=[direction
+ 'etablissement_nom', '-date_modification'])
99 def order_by_pays(self
, direction
=''):
100 return self
.extra(select
=dict(
101 pays_etablissement
='''(SELECT nom FROM ref_pays
102 WHERE ref_pays.code = IFNULL(ref_etablissement.pays, chercheurs_chercheur.etablissement_autre_pays))'''
103 ), order_by
=[direction
+ 'pays_etablissement', '-date_modification'])
105 class ChercheurSphinxQuerySet(SEPSphinxQuerySet
):
107 def __init__(self
, model
=None):
108 return SEPSphinxQuerySet
.__init__(self
, model
=model
, index
='savoirsenpartage_chercheurs',
109 weights
=dict(nom
=2, prenom
=2))
111 def filter_region(self
, region
):
112 return self
.filter(region_id
=region
.id)
114 def filter_groupe(self
, groupe
):
115 return self
.filter(groupe_ids
=groupe
.id)
117 def filter_pays(self
, pays
):
118 return self
.filter(pays_id
=pays
.id)
120 NORD_SUD_CODES
= {'Nord': 1, 'Sud': 2}
121 def filter_nord_sud(self
, nord_sud
):
122 return self
.filter(nord_sud
=self
.NORD_SUD_CODES
[nord_sud
])
124 GENRE_CODES
= dict([(k
, i
+1) for i
, (k
, v
) in enumerate(GENRE_CHOICES
)])
125 def filter_genre(self
, genre
):
126 return self
.filter(genre
=self
.GENRE_CODES
[genre
])
128 STATUT_CODES
= {'enseignant': 1, 'etudiant': 2, 'independant': 3}
129 def filter_statut(self
, statut
):
130 return self
.filter(statut
=self
.STATUT_CODES
[statut
])
132 def filter_expert(self
):
133 return self
.filter(expert
=True)
135 def filter_date_modification(self
, min=None, max=None):
136 return self
._filter_date('date_modification', min=min, max=max)
138 def order_by_nom(self
, direction
=''):
139 return self
.order_by(direction
+ 'nom_complet', '-date_modification')
141 def order_by_etablissement(self
, direction
=''):
142 return self
.order_by(direction
+ 'etablissement_attr', '-date_modification')
144 def order_by_pays(self
, direction
=''):
145 return self
.order_by(direction
+ 'pays_attr', '-date_modification')
147 class ChercheurManager(SEPManager
):
149 def get_query_set(self
):
150 return ChercheurQuerySet(self
.model
).filter(actif
=True)
152 def get_sphinx_query_set(self
):
153 return ChercheurSphinxQuerySet(self
.model
).order_by('-date_modification')
155 def filter_region(self
, region
):
156 """Le filtrage de chercheurs par région n'est pas une recherche texte."""
157 return self
.get_query_set().filter_region(region
)
159 def filter_groupe(self
, groupe
):
160 return self
.get_query_set().filter_groupe(groupe
)
162 def filter_pays(self
, pays
):
163 return self
.get_query_set().filter_pays(pays
)
165 def filter_nord_sud(self
, nord_sud
):
166 return self
.get_query_set().filter_nord_sud(nord_sud
)
168 def filter_genre(self
, genre
):
169 return self
.get_query_set().filter_genre(genre
=genre
)
171 def filter_statut(self
, statut
):
172 return self
.get_query_set().filter_statut(statut
)
174 def filter_expert(self
):
175 return self
.get_query_set().filter_expert()
177 def filter_date_modification(self
, min=None, max=None):
178 return self
.get_query_set().filter_date_modification(min=min, max=max)
180 def order_by_nom(self
, direction
=''):
181 return self
.get_query_set().order_by_nom(self
, direction
=direction
)
183 def order_by_etablissement(self
, direction
=''):
184 return self
.get_query_set().order_by_etablissement(self
, direction
=direction
)
186 def order_by_pays(self
, direction
=''):
187 return self
.get_query_set().order_by_pays(self
, direction
=direction
)
190 ('enseignant', 'Enseignant-chercheur dans un établissement'),
191 ('etudiant', 'Étudiant-chercheur doctorant'),
192 ('independant', 'Chercheur indépendant docteur')
195 class Chercheur(Personne
):
196 RESEAU_INSTITUTIONNEL_CHOICES
= (
197 ('AFELSH', 'Association des facultés ou établissements de lettres et sciences humaines des universités d’expression française (AFELSH)'),
198 ('CIDEGEF', 'Conférence internationale des dirigeants des institutions d’enseignement supérieur et de recherche de gestion d’expression française (CIDEGEF)'),
199 ('RIFEFF', 'Réseau international francophone des établissements de formation de formateurs (RIFEFF)'),
200 ('CIDMEF', 'Conférence internationale des doyens des facultés de médecine d’expression française (CIDMEF)'),
201 ('CIDCDF', 'Conférence internationale des doyens des facultés de chirurgie dentaire d’expression totalement ou partiellement française (CIDCDF)'),
202 ('CIFDUF', 'Conférence internationale des facultés de droit ayant en commun l’usage du français (CIFDUF)'),
203 ('CIRUISEF', 'Conférence internationale des responsables des universités et institutions à dominante scientifique et technique d’expression française (CIRUISEF)'),
204 ('Theophraste', 'Réseau Théophraste (Réseau de centres francophones de formation au journalisme)'),
205 ('CIDPHARMEF', 'Conférence internationale des doyens des facultés de pharmacie d’expression française (CIDPHARMEF)'),
206 ('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)'),
207 ('CITEF', 'Conférence internationale des formations d’ingénieurs et techniciens d’expression française (CITEF)'),
208 ('APERAU', 'Association pour la promotion de l’enseignement et de la recherche en aménagement et urbanisme (APERAU)'),
210 INSTANCE_AUF_CHOICES
= (
211 ('CASSOC', 'Conseil associatif'),
212 ('CA', "Conseil d'administration"),
213 ('CS', 'Conseil scientifique'),
214 ('CRE', "Commission régionale d'experts"),
215 ('CR', 'Conférence des recteurs'),
216 ('CNO', "Conseil national d'orientation")
219 nationalite
= models
.ForeignKey(Pays
, null
= True, db_column
='nationalite', to_field
='code',
220 verbose_name
= 'nationalité', related_name
='nationalite')
221 statut
= models
.CharField(max_length
=36, choices
=STATUT_CHOICES
)
222 diplome
= models
.CharField(max_length
=255, null
=True, verbose_name
= 'diplôme le plus élevé')
223 etablissement
= models
.ForeignKey(Etablissement
, db_column
='etablissement', null
=True, blank
=True)
224 etablissement_autre_nom
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= 'autre établissement')
225 etablissement_autre_pays
= models
.ForeignKey(Pays
, null
= True, blank
=True, db_column
='etablissement_autre_pays',
226 to_field
='code', related_name
='etablissement_autre_pays',
227 verbose_name
= "pays de l'établissement")
228 attestation
= models
.BooleanField()
231 thematique
= models
.ForeignKey(Thematique
, db_column
='thematique', blank
=True, null
=True, verbose_name
='thematique')
232 mots_cles
= models
.CharField(max_length
=255, null
=True, verbose_name
='mots-clés')
233 discipline
= models
.ForeignKey(Discipline
, db_column
='discipline', null
=True, verbose_name
='Discipline')
234 theme_recherche
= models
.TextField(null
=True, blank
=True, verbose_name
='thèmes de recherche')
235 equipe_recherche
= models
.CharField(max_length
=255, blank
=True, verbose_name
='équipe de recherche')
236 url_site_web
= models
.URLField(max_length
=255, null
=True, blank
=True,
237 verbose_name
='adresse site Internet', verify_exists
=False)
238 url_blog
= models
.URLField(max_length
=255, null
=True, blank
=True, verbose_name
='blog',
240 url_reseau_social
= models
.URLField(
241 max_length
=255, null
=True, blank
=True, verbose_name
='Réseau social',
243 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, ...)"
246 groupes
= models
.ManyToManyField('Groupe', through
='AdhesionGroupe', related_name
='membres', blank
=True, verbose_name
='groupes')
248 # Activités en francophonie
249 membre_instance_auf
= models
.NullBooleanField(verbose_name
="est ou a déjà été membre d'une instance de l'AUF")
250 membre_instance_auf_nom
= models
.CharField(max_length
=10, blank
=True, choices
=INSTANCE_AUF_CHOICES
, verbose_name
="instance")
251 membre_instance_auf_fonction
= models
.CharField(max_length
=255, blank
=True, verbose_name
="fonction")
252 membre_instance_auf_dates
= models
.CharField(max_length
=255, blank
=True, verbose_name
="dates")
253 expert_oif
= models
.NullBooleanField(verbose_name
="a été sollicité par l'OIF")
254 expert_oif_details
= models
.CharField(max_length
=255, blank
=True, verbose_name
="détails")
255 expert_oif_dates
= models
.CharField(max_length
=255, blank
=True, verbose_name
="dates")
256 membre_association_francophone
= models
.NullBooleanField(verbose_name
="est membre d'une association francophone")
257 membre_association_francophone_details
= models
.CharField(max_length
=255, blank
=True, verbose_name
="nom de l'association")
258 membre_reseau_institutionnel
= models
.NullBooleanField(
259 verbose_name
="est membre des instances d'un réseau institutionnel de l'AUF"
261 membre_reseau_institutionnel_nom
= models
.CharField(
262 max_length
=15, choices
=RESEAU_INSTITUTIONNEL_CHOICES
, blank
=True,
263 verbose_name
="réseau institutionnel"
265 membre_reseau_institutionnel_fonction
= models
.CharField(
266 max_length
=255, blank
=True, verbose_name
="fonction"
268 membre_reseau_institutionnel_dates
= models
.CharField(
269 max_length
=255, blank
=True, verbose_name
="dates"
273 expertises_auf
= models
.NullBooleanField(verbose_name
="est disposé à réaliser des expertises pour l'AUF")
276 date_creation
= models
.DateField(auto_now_add
=True, db_column
='date_creation')
277 date_modification
= models
.DateField(auto_now
=True, db_column
='date_modification')
280 objects
= ChercheurManager()
281 all_objects
= models
.Manager()
283 def __unicode__(self
):
284 return u
"%s %s" % (self
.nom
.upper(), self
.prenom
.title())
286 def statut_display(self
):
287 for s
in STATUT_CHOICES
:
288 if self
.statut
== s
[0]:
293 def etablissement_display(self
):
294 return (self
.nom_etablissement
or '') + (', ' + self
.pays
.nom
if self
.pays
else '')
298 return self
.etablissement
.pays
if self
.etablissement
else self
.etablissement_autre_pays
301 def nom_etablissement(self
):
302 return self
.etablissement
.nom
if self
.etablissement
else self
.etablissement_autre_nom
306 return self
.pays
.region
309 def domaines_recherche(self
):
310 return self
.groupes
.filter(groupe_chercheur
=False)
313 def groupes_chercheur(self
):
314 return self
.groupes
.filter(groupe_chercheur
=True)
317 """Si on a donné un établissement membre, on laisse tomber l'autre établissement."""
318 if self
.etablissement
:
319 self
.etablissement_autre_nom
= None
320 self
.etablissement_autre_pays
= None
321 super(Chercheur
, self
).save()
323 def activation_token(self
):
324 return sha_constructor(settings
.SECRET_KEY
+ unicode(self
.id)).hexdigest()[::2]
326 def get_absolute_url(self
):
327 return url('chercheur', kwargs
={'id': self
.id})
329 class ChercheurVoir(Chercheur
):
333 verbose_name
= 'chercheur (visualisation)'
334 verbose_name_plural
= 'chercheur (visualisation)'
336 class Publication(models
.Model
):
337 chercheur
= models
.ForeignKey(Chercheur
, related_name
='publications')
338 auteurs
= models
.CharField(max_length
=255, blank
=True, verbose_name
='auteur(s)')
339 titre
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
='titre')
340 revue
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
='revue')
341 annee
= models
.IntegerField(null
=True, blank
=True, verbose_name
='année de publication')
342 editeur
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
='éditeur')
343 lieu_edition
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
="lieu d'édition")
344 nb_pages
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
='nombre de pages')
345 url
= models
.URLField(max_length
=255, null
=True, blank
=True, verbose_name
='lien vers la publication', verify_exists
=False)
346 #Migration des publications depuis l'ancien repertoire de chercheurs
347 publication_affichage
= models
.TextField(verbose_name
='publication', null
=True, blank
=True)
348 actif
= models
.BooleanField(editable
=False)
350 def __unicode__(self
):
351 return self
.titre
or '(Aucun)'
354 if self
.publication_affichage
and (self
.auteurs
or self
.titre
or
355 self
.revue
or self
.annee
or
356 self
.editeur
or self
.lieu_edition
357 or self
.nb_pages
or self
.url
):
358 self
.publication_affichage
= ''
359 super(Publication
, self
).save()
361 class These(models
.Model
):
362 chercheur
= models
.OneToOneField(Chercheur
, primary_key
=True)
363 titre
= models
.CharField(max_length
=255, verbose_name
='Titre')
364 annee
= models
.IntegerField(verbose_name
='Année de soutenance (réalisée ou prévue)')
365 directeur
= models
.CharField(max_length
=255, verbose_name
='Directeur')
366 etablissement
= models
.CharField(max_length
=255, verbose_name
='Établissement de soutenance')
367 nb_pages
= models
.IntegerField(verbose_name
='Nombre de pages', blank
=True, null
=True)
368 url
= models
.URLField(max_length
=255, verbose_name
='Lien vers la publication', blank
=True, verify_exists
=False)
370 def __unicode__(self
):
373 class Expertise(models
.Model
):
374 id = models
.AutoField(primary_key
=True, db_column
='id')
375 chercheur
= models
.ForeignKey(Chercheur
, related_name
='expertises')
376 nom
= models
.CharField(max_length
=255, verbose_name
= "Objet de l'expertise")
377 date
= models
.CharField(max_length
=255, blank
=True)
378 lieu
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= "Lieu de l'expertise")
379 organisme_demandeur
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= 'Organisme demandeur')
380 organisme_demandeur_visible
= models
.BooleanField(verbose_name
="Afficher l'organisme demandeur")
381 actif
= models
.BooleanField(editable
= False, db_column
='actif')
383 def __unicode__(self
):
384 return u
"%s" % (self
.nom
)
386 class GroupeManager(models
.Manager
):
387 def search(self
, text
):
388 return self
.get_query_set().filter(nom__icontains
=text
)
390 class GroupeChercheurManager(GroupeManager
):
391 def get_query_set(self
):
392 return super(GroupeChercheurManager
, self
).get_query_set().filter(groupe_chercheur
=True)
394 class DomaineRechercheManager(GroupeManager
):
395 def get_query_set(self
):
396 return super(DomaineRechercheManager
, self
).get_query_set().filter(groupe_chercheur
=False)
398 class Groupe(models
.Model
):
399 id = models
.AutoField(primary_key
=True, db_column
='id')
400 nom
= models
.CharField(max_length
=255, db_column
='nom')
401 url
= models
.URLField(max_length
=255, null
=True, blank
=True,
402 verbose_name
='Site web')
403 liste_diffusion
= models
.URLField(max_length
=255, null
=True, blank
=True,
404 verbose_name
='Liste de diffusion')
405 bulletin
= models
.URLField(max_length
=255, null
=True, blank
=True,
406 verbose_name
='Bulletin')
407 actif
= models
.BooleanField(editable
= False, db_column
='actif')
408 groupe_chercheur
= models
.BooleanField(default
=False, editable
=False, verbose_name
='Groupe de chercheur')
410 responsables
= models
.ManyToManyField(User
, related_name
='responsable_groupe', verbose_name
='gestionnaire de communauté', blank
=True)
412 recherches
= models
.ManyToManyField(Search
, related_name
='recherche_groupe', verbose_name
='recherches prédéfinies', blank
=True)
414 page_accueil
= models
.TextField(null
=True, blank
=True)
416 objects
= GroupeManager()
417 groupe_chercheur_objects
= GroupeChercheurManager()
418 domaine_recherche_objects
= DomaineRechercheManager()
422 verbose_name
= 'domaine de recherche'
423 verbose_name_plural
= 'domaines de recherche'
425 def __unicode__(self
):
426 return u
"%s" % (self
.nom
)
428 def get_absolute_url(self
):
429 return url('groupe_retrieve', kwargs
={'id': self
.id})
431 def membres_actif(self
):
432 return self
.membership
.filter(statut
="accepte")
435 class GroupeChercheur(Groupe
):
436 objects
= GroupeChercheurManager()
440 verbose_name
= 'communauté de chercheurs'
441 verbose_name_plural
= 'communautés de chercheurs'
443 def save(self
, *args
, **kwargs
):
444 self
.groupe_chercheur
= True
445 super(GroupeChercheur
, self
).save(*args
, **kwargs
)
447 class DomaineRecherche(Groupe
):
448 objects
= DomaineRechercheManager()
452 verbose_name
= 'domaine de recherche'
453 verbose_name_plural
= 'domaines de recherche'
455 def save(self
, *args
, **kwargs
):
456 self
.groupe_chercheur
= False
457 super(DomaineRecherche
, self
).save(*args
, **kwargs
)
459 CG_STATUT_CHOICES
= (
460 ('nouveau', 'Nouveau'),
461 ('refuse', 'Refusé'),
462 ('accepte', 'Accepté'),
463 ('resilie', 'Résilié'),
464 ('exclus', 'Exclus'),
467 class AdhesionCommunauteManager(GroupeManager
):
468 def get_query_set(self
):
469 return super(AdhesionCommunauteManager
, self
).get_query_set().filter(groupe__groupe_chercheur
=True)
471 class AdhesionDomaineRechercheManager(GroupeManager
):
472 def get_query_set(self
):
473 return super(AdhesionDomaineRechercheManager
, self
).get_query_set().filter(groupe__groupe_chercheur
=False)
475 class AdhesionGroupe(models
.Model
):
476 id = models
.AutoField(primary_key
=True, db_column
='id')
477 chercheur
= models
.ForeignKey('Chercheur', db_column
='chercheur')
478 groupe
= models
.ForeignKey('Groupe', db_column
='groupe', related_name
="membership")
479 date_inscription
= models
.DateField(auto_now_add
=True)
480 date_modification
= models
.DateField(auto_now
=True)
481 statut
= models
.CharField(max_length
=100, choices
=CG_STATUT_CHOICES
, default
='nouveau')
484 verbose_name
= 'adhésion aux groupes'
485 verbose_name_plural
= 'adhésions aux groupes'
486 ordering
= ['chercheur']
488 def save(self
, *args
, **kwargs
):
490 old_instance
= AdhesionGroupe
.objects
.get(pk
=self
.pk
)
491 if old_instance
.statut
=='nouveau' and self
.statut
=='accepte':
492 from django
.template
.loader
import get_template
493 from django
.template
import Context
494 from django
.core
.mail
import send_mail
495 from django
.conf
import settings
497 template
= get_template('chercheurs/groupe_confirmation.txt')
498 domain
= settings
.SITE_DOMAIN
499 message
= template
.render(Context(dict(groupe
=self
.groupe
, domain
=domain
)))
500 send_mail('Votre inscription à Savoirs en partage', message
, None, [self
.chercheur
.courriel
])
502 super(AdhesionGroupe
, self
).save(*args
, **kwargs
)
504 def __unicode__(self
):
505 return u
"%s - %s" % (self
.chercheur
, self
.groupe
)
507 class AdhesionCommunaute(AdhesionGroupe
):
508 objects
= AdhesionCommunauteManager()
512 verbose_name
= 'adhésion aux communautés de chercheurs'
513 verbose_name_plural
= 'adhésion aux communautés de chercheurs'
515 class AdhesionDomaineRecherche(AdhesionGroupe
):
516 objects
= AdhesionDomaineRechercheManager()
520 verbose_name
= 'adhésion aux domaines de recherche'
521 verbose_name_plural
= 'adhésion aux domaines de recherche'
523 class ChercheurSearch(Search
):
524 nom_chercheur
= models
.CharField(max_length
=100, blank
=True, verbose_name
='nom')
525 domaine
= models
.ForeignKey(DomaineRecherche
, blank
=True, null
=True, verbose_name
='domaine de recherche')
526 equipe_recherche
= models
.CharField(max_length
=100, blank
=True, null
=True,
527 verbose_name
='Équipe de recherche',
528 help_text
='ou Laboratoire, ou Groupement inter-universitaire')
529 statut
= models
.CharField(max_length
=100, blank
=True, choices
=STATUT_CHOICES
+ (('expert', 'Expert'),))
530 pays
= models
.ForeignKey(Pays
, blank
=True, null
=True)
531 nord_sud
= models
.CharField(max_length
=4, blank
=True, choices
=(('Nord', 'Nord'), ('Sud', 'Sud')),
532 verbose_name
='Nord/Sud',
533 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)")
534 activites_francophonie
= models
.CharField(
535 max_length
=25, blank
=True, verbose_name
='activités en Francophonie',
536 choices
=(('instance_auf', "Membre d'une instance de l'AUF"),
537 ('expert_oif', "Sollicité par l'OIF"),
538 ('association_francophone', "Membre d'une association ou d'une société savante francophone"),
539 ('reseau_institutionnel', "Membre des instances d'un réseau institutionnel de l'AUF"))
541 genre
= models
.CharField(max_length
=1, blank
=True, choices
=GENRE_CHOICES
)
544 verbose_name
= 'recherche de chercheurs'
545 verbose_name_plural
= 'recherches de chercheurs'
547 def run(self
, min_date
=None, max_date
=None):
548 results
= Chercheur
.objects
550 results
= results
.search(self
.q
)
551 if self
.nom_chercheur
:
552 results
= results
.add_to_query('@(nom,prenom) ' + self
.nom_chercheur
)
553 if self
.equipe_recherche
:
554 results
= results
.add_to_query('@equipe_recherche ' + self
.equipe_recherche
)
556 results
= results
.filter_discipline(self
.discipline
)
558 results
= results
.filter_region(self
.region
)
560 if self
.statut
== "expert":
561 results
= results
.filter_expert()
563 results
= results
.filter_statut(self
.statut
)
565 results
= results
.filter_groupe(self
.domaine
)
567 results
= results
.filter_pays(self
.pays
)
569 results
= results
.filter_nord_sud(self
.nord_sud
)
571 results
= results
.filter_genre(self
.genre
)
572 if self
.activites_francophonie
== 'instance_auf':
573 results
= results
.filter(membre_instance_auf
=True)
574 elif self
.activites_francophonie
== 'expert_oif':
575 results
= results
.filter(expert_oif
=True)
576 elif self
.activites_francophonie
== 'association_francophone':
577 results
= results
.filter(membre_association_francophone
=True)
578 elif self
.activites_francophonie
== 'reseau_institutionnel':
579 results
= results
.filter(membre_reseau_institutionnel
=True)
581 results
= results
.filter_date_modification(min=min_date
)
583 results
= results
.filter_date_modification(max=max_date
)
587 qs
= self
.query_string()
588 return url('chercheurs') + ('?' + qs
if qs
else '')
591 qs
= self
.query_string()
592 return url('rss_chercheurs') + ('?' + qs
if qs
else '')
594 def get_email_alert_content(self
, results
):
596 for chercheur
in results
:
597 content
+= u
'- [%s %s](%s%s) \n' % (chercheur
.nom
.upper(),
599 settings
.SITE_ROOT_URL
,
600 chercheur
.get_absolute_url())
601 content
+= u
' %s\n\n' % chercheur
.etablissement_display
604 class GroupeSearch(Search
):
607 verbose_name
= 'recherche de groupe'
608 verbose_name_plural
= 'recherches de groupes'
611 results
= Groupe
.groupe_chercheur_objects
613 results
= results
.search(self
.q
)
617 # qs = self.query_string()
618 # return url('groupes') + ('?' + qs if qs else '')
621 # qs = self.query_string()
622 # return url('rss_groupes') + ('?' + qs if qs else '')
624 class Message(models
.Model
):
626 chercheur
= models
.ForeignKey('Chercheur', db_column
='chercheur')
627 groupe
= models
.ForeignKey('Groupe', db_column
='groupe')
628 titre
= models
.CharField(max_length
=255)
629 contenu
= models
.TextField()
631 date_creation
= models
.DateTimeField(auto_now_add
=True, db_column
='date_creation')
634 ordering
= ['-date_creation']
636 def __unicode__(self
):
637 return u
"%s - %s" % (self
.chercheur
, self
.titre
)
639 def get_absolute_url(self
):
640 return url('groupe_messages', kwargs
={'id': self
.groupe
.id})
643 class AuthLDAP(models
.Model
):
644 username
= models
.CharField('utilisateur', max_length
=255, unique
=True)
645 ldap_hash
= models
.CharField('hash LDAP', max_length
=255)
646 date_modification
= models
.DateTimeField(auto_now
=True)
648 def __unicode__(self
):