1 # -*- encoding: utf-8 -*-
3 from datamaster_modeles
.models
import *
4 from django
.db
import models
5 from django
.db
.models
import Q
6 from django
.utils
.encoding
import smart_str
7 from djangosphinx
.models
import SphinxSearch
8 from savoirs
.models
import Discipline
, SEPManager
, SEPSphinxQuerySet
, SEPQuerySet
10 GENRE_CHOICES
= (('m', 'Homme'), ('f', 'Femme'))
11 class Personne(models
.Model
):
13 id = models
.AutoField(primary_key
=True)
14 salutation
= models
.CharField(max_length
=128, null
= True, blank
= True)
15 nom
= models
.CharField(max_length
=255)
16 prenom
= models
.CharField(max_length
=128, verbose_name
= 'Prénom')
17 courriel
= models
.EmailField(max_length
=128, unique
=True, verbose_name
="Adresse électronique")
18 fonction
= models
.CharField(max_length
=128, null
= True, blank
= True)
19 date_naissance
= models
.DateField(null
=True, blank
=True)
20 sousfonction
= models
.CharField(max_length
=128, null
= True, blank
= True,
21 verbose_name
= 'Sous-fonction')
22 mobile
= models
.CharField(max_length
=32, null
= True, blank
= True,
23 verbose_name
= 'Numéro de téléphone portable ')
24 genre
= models
.CharField(max_length
=1, choices
=GENRE_CHOICES
)
25 commentaire
= models
.TextField(verbose_name
= 'Commentaires', null
= True,
27 actif
= models
.BooleanField(editable
= False)
29 def __unicode__(self
):
30 return u
"%s %s, %s" % (self
.prenom
, self
.nom
, self
.courriel
)
33 ordering
= ["prenom", "nom"]
35 class Utilisateur(Personne
):
36 encrypted_password
= models
.CharField(db_column
='password', max_length
=35, verbose_name
= 'Mot de passe')
38 def set_password(self
, clear_password
):
39 self
.encrypted_password
= self
.encrypt_password(clear_password
)
41 def check_password(self
, clear_password
):
42 return self
.encrypted_password
== self
.encrypt_password(clear_password
)
44 def encrypt_password(self
, clear_password
):
45 return hashlib
.md5(smart_str(clear_password
)).hexdigest()
47 def get_new_password_code(self
):
48 return hashlib
.md5(smart_str(self
.courriel
+ self
.encrypted_password
)).hexdigest()[0:6]
50 class ChercheurQuerySet(SEPQuerySet
):
52 def filter_groupe(self
, groupe
):
53 return self
.filter(groupes
=groupe
)
55 def filter_pays(self
, pays
):
56 return self
.filter(Q(etablissement__pays
=pays
) |
Q(etablissement_autre_pays
=pays
))
58 def filter_region(self
, region
):
59 return self
.filter(Q(etablissement__pays__region
=region
) |
Q(etablissement_autre_pays__region
=region
))
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
))
64 def filter_statut(self
, statut
):
65 return self
.filter(statut
=statut
)
67 def filter_expert(self
):
68 return self
.exclude(expertises
=None)
70 class ChercheurSphinxQuerySet(SEPSphinxQuerySet
):
72 def __init__(self
, model
=None):
73 return SEPSphinxQuerySet
.__init__(self
, model
=model
, index
='chercheurs',
74 weights
=dict(nom
=2, prenom
=2))
76 def filter_region(self
, region
):
77 return self
.filter(region_id
=region
.id)
79 def filter_groupe(self
, groupe
):
80 return self
.filter(groupe_ids
=groupe
.id)
82 def filter_pays(self
, pays
):
83 return self
.filter(pays_id
=pays
.id)
85 NORD_SUD_CODES
= {'Nord': 1, 'Sud': 2}
86 def filter_nord_sud(self
, nord_sud
):
87 return self
.filter(nord_sud
=self
.NORD_SUD_CODES
[nord_sud
])
89 STATUT_CODES
= {'enseignant': 1, 'etudiant': 2, 'independant': 3}
90 def filter_statut(self
, statut
):
91 return self
.filter(statut
=self
.STATUT_CODES
[statut
])
93 def filter_expert(self
):
94 return self
.filter(expert
=1)
96 class ChercheurManager(SEPManager
):
98 def get_query_set(self
):
99 return ChercheurQuerySet(self
.model
)
101 def get_sphinx_query_set(self
):
102 return ChercheurSphinxQuerySet(self
.model
).order_by('-date_modification')
104 def filter_region(self
, region
):
105 """Le filtrage de chercheurs par région n'est pas une recherche texte."""
106 return self
.get_query_set().filter_region(region
)
108 def filter_groupe(self
, groupe
):
109 return self
.get_query_set().filter_groupe(groupe
)
111 def filter_pays(self
, pays
):
112 return self
.get_query_set().filter_pays(pays
)
114 def filter_nord_sud(self
, nord_sud
):
115 return self
.get_query_set().filter_nord_sud(nord_sud
)
117 def filter_statut(self
, statut
):
118 return self
.get_query_set().filter_statut(statut
)
120 def filter_expert(self
):
121 return self
.get_query_set().filter_expert()
123 STATUT_CHOICES
= (('enseignant', 'Enseignant-chercheur dans un établissement'), ('etudiant', 'Étudiant-chercheur doctorant'), ('independant', 'Chercheur indépendant docteur'))
124 class Chercheur(models
.Model
):
125 id = models
.AutoField(primary_key
=True, db_column
='id')
126 personne
= models
.ForeignKey('Personne', db_column
='personne', editable
=False)
127 nationalite
= models
.ForeignKey(Pays
, null
= True, db_column
='nationalite', to_field
='code',
128 verbose_name
= 'nationalité', related_name
='nationalite')
129 #fonction = models.CharField(max_length=36, choices=FONCTION_CHOICES)
130 statut
= models
.CharField(max_length
=36, choices
=STATUT_CHOICES
)
131 diplome
= models
.CharField(max_length
=255, null
=True, verbose_name
= 'diplôme le plus élevé')
132 etablissement
= models
.ForeignKey(Etablissement
, db_column
='etablissement', null
=True, blank
=True)
133 etablissement_autre_nom
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= 'autre établissement')
134 etablissement_autre_pays
= models
.ForeignKey(Pays
, null
= True, blank
=True, db_column
='etablissement_autre_pays',
135 to_field
='code', related_name
='etablissement_autre_pays',
136 verbose_name
= "pays de l'établissement")
139 thematique
= models
.ForeignKey(Thematique
, db_column
='thematique', null
=True, verbose_name
='thematique')
140 mots_cles
= models
.CharField(max_length
=255, null
=True, verbose_name
='mots-clés')
141 discipline
= models
.ForeignKey(Discipline
, db_column
='discipline', null
=True, verbose_name
='Discipline')
142 theme_recherche
= models
.TextField(null
=True, blank
=True, verbose_name
='thèmes de recherche')
143 groupe_recherche
= models
.CharField(max_length
=255, blank
=True, verbose_name
='groupe de recherche')
144 url_site_web
= models
.URLField(max_length
=255, null
=True, blank
=True, verbose_name
='adresse site Internet')
145 url_blog
= models
.URLField(max_length
=255, null
=True, blank
=True, verbose_name
='blog')
146 url_reseau_social
= models
.URLField(
147 max_length
=255, null
=True, blank
=True, verbose_name
='Réseau social',
148 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, ...)"
151 groupes
= models
.ManyToManyField('Groupe', through
='ChercheurGroupe', blank
=True, verbose_name
='Domaines de recherche')
153 #Refactoring, mettre les publications comme etant des many2many;
154 publication1
= models
.ForeignKey('Publication',
155 db_column
='publication1', null
=True,
156 blank
=True, editable
=False,
157 related_name
='publication1',
158 verbose_name
='Publication 1')
159 publication2
= models
.ForeignKey('Publication',
160 db_column
='publication2', null
=True,
161 blank
=True, editable
=False,
162 related_name
='publication2',
163 verbose_name
= 'Publication 2')
164 publication3
= models
.ForeignKey('Publication',
165 db_column
='publication3', null
=True,
166 blank
=True, editable
=False,
167 related_name
='publication3',
168 verbose_name
= 'Publication 3')
169 publication4
= models
.ForeignKey('Publication',
170 db_column
='publication4', null
=True,
171 blank
=True, editable
=False,
172 related_name
='publication4',
173 verbose_name
= 'Publication 4')
175 these
= models
.ForeignKey('Publication', db_column
='these', null
=True,
176 blank
=True, related_name
='These', editable
=False)
178 # Activités en francophonie
179 membre_instance_auf
= models
.BooleanField(default
=False, verbose_name
="est ou a déjà été membre d'une instance de l'AUF")
180 membre_instance_auf_details
= models
.CharField(max_length
=255, blank
=True, verbose_name
="détails")
181 membre_instance_auf_dates
= models
.CharField(max_length
=255, blank
=True, verbose_name
="dates")
182 expert_oif
= models
.BooleanField(default
=False, verbose_name
="a été sollicité par l'OIF")
183 expert_oif_details
= models
.CharField(max_length
=255, blank
=True, verbose_name
="détails")
184 expert_oif_dates
= models
.CharField(max_length
=255, blank
=True, verbose_name
="dates")
185 membre_association_francophone
= models
.BooleanField(default
=False, verbose_name
="est membre d'une association francophone")
186 membre_association_francophone_details
= models
.CharField(max_length
=255, blank
=True, verbose_name
="nom de l'association")
187 membre_reseau_institutionnel
= models
.BooleanField(
188 default
=False, verbose_name
="a fait partie des instances d'un réseau institutionnel de l'AUF"
190 membre_reseau_institutionnel_details
= models
.CharField(
191 max_length
=255, blank
=True, verbose_name
="instances et fonction"
193 membre_reseau_institutionnel_dates
= models
.CharField(
194 max_length
=255, blank
=True, verbose_name
="dates"
198 actif
= models
.BooleanField(editable
= False)
199 date_creation
= models
.DateField(auto_now_add
=True, db_column
='date_creation')
200 date_modification
= models
.DateField(auto_now
=True, db_column
='date_modification')
203 objects
= ChercheurManager()
204 all_objects
= models
.Manager()
206 def __unicode__(self
):
207 return u
"%s %s" % (self
.personne
.nom
.upper(), self
.personne
.prenom
.title())
209 def statut_display(self
):
210 for s
in STATUT_CHOICES
:
211 if self
.statut
== s
[0]:
216 def etablissement_display(self
):
217 if self
.etablissement
:
218 return self
.etablissement
.nom
+ ', ' + self
.etablissement
.pays
.nom
220 return self
.etablissement_autre_nom
+ ', ' + self
.etablissement_autre_pays
.nom
224 return self
.etablissement
.pays
if self
.etablissement
else self
.etablissement_autre_pays
228 return self
.pays
.region
231 """Si on a donné un établissement membre, on laisse tomber l'autre établissement."""
232 if self
.etablissement
:
233 self
.etablissement_autre_nom
= None
234 self
.etablissement_autre_pays
= None
235 super(Chercheur
, self
).save()
237 class Publication(models
.Model
):
238 id = models
.AutoField(primary_key
=True, db_column
='id')
239 titre
= models
.CharField(max_length
=255, db_column
='titre', null
=True, blank
=True, verbose_name
= 'Titre')
240 revue
= models
.CharField(max_length
=255, db_column
='revue', null
=True, blank
=True, verbose_name
= 'Revue')
241 annee
= models
.IntegerField(db_column
='annee', null
=True, blank
=True, verbose_name
='Année de publication')
242 editeur
= models
.CharField(max_length
=255, db_column
='editeur', null
=True, blank
=True, verbose_name
= 'Éditeur')
243 lieu_edition
= models
.CharField(max_length
=255, db_column
='lieu_edition', null
=True, blank
=True, verbose_name
= 'Lieu d\'édition')
244 nb_pages
= models
.CharField(max_length
=255, db_column
='nb_pages', null
=True, blank
=True, verbose_name
= 'Nombre de pages')
245 url
= models
.CharField(max_length
=255, db_column
='url', null
=True, blank
=True, verbose_name
= 'Lien vers la publication')
246 #Migration des publications depuis l'ancien repertoire de chercheurs
247 publication_affichage
= models
.TextField(verbose_name
= 'Publication', null
= True,
249 actif
= models
.BooleanField(editable
= False, db_column
='actif')
251 def __unicode__(self
):
252 return u
"%s" % (self
.titre
)
254 class Expertise(models
.Model
):
255 id = models
.AutoField(primary_key
=True, db_column
='id')
256 chercheur
= models
.ForeignKey(Chercheur
, related_name
='expertises')
257 nom
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= "Objet de l'expertise")
258 date
= models
.CharField(max_length
=255, blank
=True)
259 lieu
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= "Lieu de l'expertise")
260 organisme_demandeur
= models
.CharField(max_length
=255, null
=True, blank
=True, verbose_name
= 'Organisme demandeur')
261 organisme_demandeur_visible
= models
.BooleanField(verbose_name
="Afficher l'organisme demandeur")
262 actif
= models
.BooleanField(editable
= False, db_column
='actif')
264 def __unicode__(self
):
265 return u
"%s" % (self
.nom
)
267 class Groupe(models
.Model
):
268 id = models
.AutoField(primary_key
=True, db_column
='id')
269 nom
= models
.CharField(max_length
=255, db_column
='nom')
270 url
= models
.URLField(max_length
=255, null
=True, blank
=True,
271 verbose_name
='Site web')
272 liste_diffusion
= models
.URLField(max_length
=255, null
=True, blank
=True,
273 verbose_name
='Liste de diffusion')
274 bulletin
= models
.URLField(max_length
=255, null
=True, blank
=True,
275 verbose_name
='Bulletin')
276 actif
= models
.BooleanField(editable
= False, db_column
='actif')
279 verbose_name
= 'domaine de recherche'
280 verbose_name_plural
= 'domaines de recherche'
282 def __unicode__(self
):
283 return u
"%s" % (self
.nom
)
285 class ChercheurGroupe(models
.Model
):
286 id = models
.AutoField(primary_key
=True, db_column
='id')
287 chercheur
= models
.ForeignKey('Chercheur', db_column
='chercheur', editable
=False)
288 groupe
= models
.ForeignKey('Groupe', db_column
='groupe')
289 date_inscription
= models
.DateField(auto_now_add
=True)
290 date_modification
= models
.DateField(auto_now
=True)
291 actif
= models
.BooleanField(editable
= False, db_column
='actif')
294 verbose_name
= 'adhésion'
296 def __unicode__(self
):
297 return u
"%s - %s" % (self
.chercheur
, self
.groupe
)