1 # -*- coding: utf-8 -*-
2 from django
.db
import models
3 from django
.db
.models
import Q
4 from django
.contrib
import admin
5 from django
.core
.urlresolvers
import reverse
as url
6 from django
.forms
.models
import BaseInlineFormSet
7 from django
.http
import HttpResponseRedirect
8 from django
.utils
.encoding
import smart_str
9 from django_exportateur
.exportateur
import exportateur
11 from chercheurs
.models
import Chercheur
, ChercheurVoir
, Publication
, \
12 GroupeChercheur
, DomaineRecherche
, \
13 AdhesionGroupe
, ChercheurQuerySet
, These
14 from savoirs
.models
import Search
16 class ChercheurAdmin(admin
.ModelAdmin
):
17 list_filter
= ['genre']
18 alphabet_filter
= 'nom'
19 alphabet_filter_table
= 'chercheurs_personne'
22 actions
= ('remove_from_group', 'export_as_ods', 'export_as_csv')
23 search_fields
= ('nom', 'prenom')
25 def lookup_allowed(self
, lookup
, value
):
26 return lookup
in ['genre', 'statut', 'membre_reseau_institutionnel',
27 'membre_instance_auf', 'discipline', 'region', 'pays',
28 'groupes', 'nord_sud'] or \
29 admin
.ModelAdmin
.lookup_allowed(self
, lookup
, value
)
31 def remove_from_group(self
, request
, queryset
):
32 groupe_id
= request
.GET
.get('groupes__id__exact')
33 chercheur_ids
= queryset
.values_list('id', flat
=True)
34 matches
= AdhesionGroupe
.objects
.filter(groupe
=groupe_id
, chercheur__in
=chercheur_ids
)
36 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist') + '?groupes__id__exact=' + groupe_id
)
38 def get_actions(self
, request
):
39 actions
= super(ChercheurAdmin
, self
).get_actions(request
)
41 # Si on filtre par groupes, offrir d'en retirer les
42 # chercheurs sélectionnés.
43 groupe_id
= request
.GET
.get('groupes__id__exact')
45 groupe
= Groupe
.objects
.get(id=groupe_id
)
46 action_desc
= actions
['remove_from_group']
47 actions
['remove_from_group'] = (action_desc
[0], action_desc
[1], u
'Retirer du domaine de recherche « %s »' % groupe
.nom
)
49 del actions
['remove_from_group']
52 def queryset(self
, request
):
53 return ChercheurAdminQuerySet(Chercheur
)
55 def get_object(self
, request
, object_id
):
56 """On doit réimplémenter cette méthode à cause de ce qu'on fait avec "initial" dans la méthode queryset()."""
58 return Chercheur
.objects
.get(id=object_id
)
59 except Chercheur
.DoesNotExist
:
62 def export(self
, queryset
, type):
63 if queryset
.count() == 0:
66 headers
= ['Nom', 'Prénom', 'Genre', 'Courriel', 'Téléphone', 'Adresse postale',
67 'Statut', 'Diplôme', 'Établissement', 'Pays', 'Domaines de recherche',
68 'Thèse', 'Directeur', 'Discipline', 'Thèmes de recherche', 'Équipe de recherche', 'Mots-clés',
69 'Site web', 'Blog', 'Réseau social',
70 'Membre instance AUF', "Sollicité par l'OIF", 'Membre société francophone',
71 'Membre instance réseau institutionnel AUF', 'Expertises', 'Solliciter pour expertises',
78 row
.append(c
.get_genre_display())
79 row
.append(c
.courriel
)
80 row
.append(c
.telephone
)
81 row
.append(c
.adresse_postale
)
82 row
.append(c
.get_statut_display())
84 row
.append(c
.nom_etablissement
)
86 row
.append(', '.join(g
.nom
for g
in c
.groupes
.all()))
89 row
.append('%s, %s, %s, %s pages.' % (t
.titre
, t
.etablissement
, t
.annee
, t
.nb_pages
))
90 row
.append(t
.directeur
)
91 except These
.DoesNotExist
:
94 row
.append(c
.discipline
.nom
if c
.discipline
else '')
95 row
.append(c
.theme_recherche
)
96 row
.append(c
.equipe_recherche
)
97 row
.append(c
.mots_cles
)
98 row
.append(c
.url_site_web
)
99 row
.append(c
.url_blog
)
100 row
.append(c
.url_reseau_social
)
101 if c
.membre_instance_auf
:
102 row
.append(', '.join([c
.membre_instance_auf_nom
, c
.membre_instance_auf_fonction
, c
.membre_instance_auf_dates
]))
106 row
.append(', '.join([c
.expert_oif_details
, c
.expert_oif_dates
]))
109 if c
.membre_association_francophone
:
110 row
.append(c
.membre_association_francophone_details
)
113 if c
.membre_reseau_institutionnel
:
114 row
.append(', '.join([c
.membre_reseau_institutionnel_nom
, c
.membre_reseau_institutionnel_fonction
, c
.membre_reseau_institutionnel_dates
]))
117 row
.append('; '.join(', '.join([e
.nom
, e
.date
, e
.organisme_demandeur
]) for e
in c
.expertises
.all()))
118 if c
.expertises_auf
is None:
121 row
.append('Oui' if c
.expertises_auf
else 'Non')
122 row
.append('; '.join(p
.publication_affichage
if p
.publication_affichage
else
123 '%s, %s, %s, %s, %s, %s, %s pages.' %
124 (p
.auteurs
, p
.titre
, p
.revue
, p
.annee
, p
.editeur
, p
.lieu_edition
, p
.nb_pages
)
125 for p
in c
.publications
.all()))
126 data
.append([smart_str(x
) if x
else '' for x
in row
])
127 return exportateur(headers
, data
, type, filename
='chercheurs.%s' % type)
129 def export_as_csv(self
, request
, queryset
):
130 return self
.export(queryset
, 'csv')
131 export_as_csv
.short_description
= 'Export CSV'
133 def export_as_ods(self
, request
, queryset
):
134 return self
.export(queryset
, 'ods')
135 export_as_ods
.short_description
= 'Export ODS'
138 class ChercheurVoirAdmin(ChercheurAdmin
):
141 fields
= ['salutation', 'nom', 'prenom', 'courriel', 'afficher_courriel',
142 'fonction', 'date_naissance', 'sousfonction', 'telephone',
143 'adresse_postale', 'genre', 'commentaire',
145 'nationalite', 'statut', 'diplome', 'etablissement',
146 'etablissement_autre_nom', 'etablissement_autre_pays',
147 'attestation', 'thematique', 'mots_cles', 'discipline',
148 'theme_recherche', 'equipe_recherche', 'url_site_web',
149 'url_blog', 'url_reseau_social',
150 'membre_instance_auf', 'membre_instance_auf_nom',
151 'membre_instance_auf_fonction', 'membre_instance_auf_dates',
152 'expert_oif', 'expert_oif_details', 'expert_oif_dates',
153 'membre_association_francophone', 'membre_association_francophone_details',
154 'membre_reseau_institutionnel', 'membre_reseau_institutionnel_nom',
155 'membre_reseau_institutionnel_fonction', 'membre_reseau_institutionnel_dates',
158 def __init__(self
, model
, admin_site
):
159 super(ChercheurVoirAdmin
, self
).__init__(model
, admin_site
)
160 self
.readonly_fields
= self
.fields
163 admin
.site
.register(ChercheurVoir
, ChercheurVoirAdmin
)
165 class ChercheurAdminQuerySet(ChercheurQuerySet
):
167 def filter(self
, *args
, **kwargs
):
168 """Gère des filtres supplémentaires pour l'admin.
170 C'est la seule façon que j'ai trouvée de contourner les mécanismes
171 de recherche de l'admin."""
172 pays
= kwargs
.pop('pays', None)
173 region
= kwargs
.pop('region', None)
174 nord_sud
= kwargs
.pop('nord_sud', None)
175 expert
= kwargs
.pop('expert', None)
178 qs
= qs
.filter(Q(etablissement__pays
=pays
) |
179 (Q(etablissement
=None) & Q(etablissement_autre_pays
=pays
)))
180 elif region
is not None:
181 qs
= qs
.filter(Q(etablissement__pays__region
=region
) |
182 (Q(etablissement
=None) & Q(etablissement_autre_pays__region
=region
)))
183 elif nord_sud
is not None:
184 qs
= qs
.filter(Q(etablissement__pays__nord_sud
=nord_sud
) |
185 (Q(etablissement
=None) & Q(etablissement_autre_pays__nord_sud
=nord_sud
)))
186 if expert
is not None:
187 if expert
in ['1', 1, True]:
188 qs
= qs
.exclude(expertises
=None)
190 qs
= qs
.filter(expertises
=None)
192 return super(ChercheurAdminQuerySet
, qs
).filter(*args
, **kwargs
)
195 class AdhesionGroupeAdmin(admin
.ModelAdmin
):
196 list_filter
= ('groupe','statut')
197 list_display
= ('groupe', 'chercheur', 'statut')
198 list_editable
= ('statut',)
199 search_fields
= ('chercheur__nom', 'chercheur__prenom')
201 alphabet_filter
= 'chercheur__nom'
202 DEFAULT_ALPHABET
= ''
204 actions
= ['assigner_cgstatut']
207 def lookup_allowed(self
, lookup
, value
):
208 return lookup
in ['chercheur__nom__istartswith'] or \
209 admin
.ModelAdmin
.lookup_allowed(self
, lookup
, value
)
211 def queryset(self
, request
):
212 qs
= super(AdhesionGroupeAdmin
, self
).queryset(request
)
214 if not request
.user
.is_superuser
and not request
.user
.has_perm('chercheurs.change_adhesiongroupe'):
215 qs
= qs
.filter(groupe__responsables
=request
.user
)
219 def has_change_permission(self
, request
, obj
=None):
222 if request
.user
.responsable_groupe
.count():
225 if request
.user
in obj
.groupe
.responsables
.all():
228 return super(AdhesionGroupeAdmin
, self
).has_change_permission(request
, obj
)
230 def assigner_cgstatut(self
, request
, queryset
):
231 selected
= request
.POST
.getlist(admin
.ACTION_CHECKBOX_NAME
)
232 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('cgstatut', ",".join(selected
)))
233 assigner_cgstatut
.short_description
= u
'Assigner un statut'
236 class BaseGroupeAdmin(admin
.ModelAdmin
):
238 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion',
239 'bulletin', 'page_accueil')}),
240 (('Gestionnaire de communauté'), {'fields': ('responsables',)}),
241 (('Recherches prédéfinies'), {'fields': ('recherches',)}),
245 js
= ['js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js']
247 def save_model(self
, request
, obj
, form
, change
):
248 responsables
= form
.cleaned_data
['responsables']
249 for user
in responsables
:
253 if not request
.user
.is_superuser
:
254 recherches
= Search
.objects
.exclude(user
=request
.user
)
255 form
.cleaned_data
['recherches'] = form
.cleaned_data
['recherches'] | recherches
257 super(BaseGroupeAdmin
, self
).save_model(request
, obj
, form
, change
)
259 def queryset(self
, request
):
260 qs
= super(BaseGroupeAdmin
, self
).queryset(request
)
262 if not request
.user
.is_superuser
and not request
.user
.has_perm('chercheurs.change_groupechercheur'):
263 qs
= qs
.filter(responsables
=request
.user
)
267 def has_change_permission(self
, request
, obj
=None, groupe_chercheur
=False):
270 if request
.user
.responsable_groupe
.filter(groupe_chercheur
=groupe_chercheur
).count():
273 if request
.user
in obj
.responsables
.all():
276 return super(BaseGroupeAdmin
, self
).has_change_permission(request
, obj
)
278 def formfield_for_manytomany(self
, db_field
, request
, **kwargs
):
279 if db_field
.name
== "recherches" and not request
.user
.is_superuser
:
280 kwargs
["queryset"] = Search
.objects
.filter(user
=request
.user
)
281 return db_field
.formfield(**kwargs
)
282 return super(BaseGroupeAdmin
, self
).formfield_for_manytomany(db_field
, request
, **kwargs
)
285 class GroupeChercheurAdmin(BaseGroupeAdmin
):
287 def has_change_permission(self
, request
, obj
=None):
288 return super(GroupeChercheurAdmin
, self
).has_change_permission(request
, obj
, groupe_chercheur
=True)
291 class DomaineRechercheAdmin(BaseGroupeAdmin
):
293 def has_change_permission(self
, request
, obj
=None):
294 return super(DomaineRechercheAdmin
, self
).has_change_permission(request
, obj
, groupe_chercheur
=False)
296 class PublicationAdmin(admin
.ModelAdmin
):
297 search_fields
= ('auteurs', 'titre', 'revue', 'editeur')
300 admin
.site
.register(Chercheur
, ChercheurAdmin
)
301 admin
.site
.register(Publication
, PublicationAdmin
)
302 admin
.site
.register(GroupeChercheur
, GroupeChercheurAdmin
)
303 admin
.site
.register(DomaineRecherche
, DomaineRechercheAdmin
)
304 admin
.site
.register(AdhesionGroupe
, AdhesionGroupeAdmin
)