Groupes, admin: Liste les membres acceptés
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / admin.py
CommitLineData
6f8d521e 1# -*- coding: utf-8 -*-
cbae0173 2from django.db import models
6f8d521e 3from django.db.models import Q
cbae0173 4from django.contrib import admin
55ef8558
EMS
5from django.core.urlresolvers import reverse as url
6from django.forms.models import BaseInlineFormSet
7from django.http import HttpResponseRedirect
d264c787
EMS
8from django.utils.encoding import smart_str
9from django_exportateur.exportateur import exportateur
cbae0173 10
81fe476e
PP
11from chercheurs.models import Chercheur, ChercheurVoir, Publication, \
12 GroupeChercheur, DomaineRecherche, \
13 ChercheurGroupe, ChercheurQuerySet, These
2094c7e5 14from savoirs.models import Search
6f8d521e 15
55ef8558 16class ChercheurAdmin(admin.ModelAdmin):
6f8d521e 17 list_filter = ['genre']
b1d4c7ac
PP
18 alphabet_filter = 'nom'
19 alphabet_filter_table = 'chercheurs_personne'
20 DEFAULT_ALPHABET = ''
21
d264c787 22 actions = ('remove_from_group', 'export_as_ods', 'export_as_csv')
62354bdb 23 search_fields = ('nom', 'prenom')
cbae0173 24
afc30c28 25 def lookup_allowed(self, lookup, value):
6f8d521e
EMS
26 return lookup in ['genre', 'statut', 'membre_reseau_institutionnel',
27 'membre_instance_auf', 'discipline', 'region', 'pays',
b1d4c7ac 28 'groupes', 'nord_sud'] or \
afc30c28 29 admin.ModelAdmin.lookup_allowed(self, lookup, value)
c0d2903e 30
55ef8558
EMS
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 = ChercheurGroupe.objects.filter(groupe=groupe_id, chercheur__in=chercheur_ids)
35 matches.delete()
36 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist') + '?groupes__id__exact=' + groupe_id)
37
38 def get_actions(self, request):
39 actions = super(ChercheurAdmin, self).get_actions(request)
40
41 # Si on filtre par groupe de recherche, offrir d'en retirer les
42 # chercheurs sélectionnés.
43 groupe_id = request.GET.get('groupes__id__exact')
44 if groupe_id:
45 groupe = Groupe.objects.get(id=groupe_id)
46 action_desc = actions['remove_from_group']
e7b9234a 47 actions['remove_from_group'] = (action_desc[0], action_desc[1], u'Retirer du domaine de recherche « %s »' % groupe.nom)
55ef8558
EMS
48 else:
49 del actions['remove_from_group']
50 return actions
51
6f8d521e
EMS
52 def queryset(self, request):
53 return ChercheurAdminQuerySet(Chercheur)
54
ee2ef0e8
EMS
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()."""
57 try:
58 return Chercheur.objects.get(id=object_id)
59 except Chercheur.DoesNotExist:
60 return None
61
d264c787
EMS
62 def export(self, queryset, type):
63 if queryset.count() == 0:
64 return None
65 obj = queryset[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', 'Groupe 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',
72 'Publications']
73 data = []
74 for c in queryset:
75 row = []
76 row.append(c.nom)
77 row.append(c.prenom)
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())
83 row.append(c.diplome)
84 row.append(c.nom_etablissement)
85 row.append(c.pays)
86 row.append(', '.join(g.nom for g in c.groupes.all()))
87 try:
88 t = c.these
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:
92 row.append('')
93 row.append('')
94 row.append(c.discipline.nom if c.discipline else '')
95 row.append(c.theme_recherche)
96 row.append(c.groupe_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]))
103 else:
104 row.append('')
105 if c.expert_oif:
106 row.append(', '.join([c.expert_oif_details, c.expert_oif_dates]))
107 else:
108 row.append('')
109 if c.membre_association_francophone:
110 row.append(c.membre_association_francophone_details)
111 else:
112 row.append('')
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]))
115 else:
116 row.append('')
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:
119 row.append('')
120 else:
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)
128
129 def export_as_csv(self, request, queryset):
130 return self.export(queryset, 'csv')
131 export_as_csv.short_description = 'Export CSV'
132
133 def export_as_ods(self, request, queryset):
134 return self.export(queryset, 'ods')
135 export_as_ods.short_description = 'Export ODS'
136
81fe476e
PP
137
138class ChercheurVoirAdmin(ChercheurAdmin):
139
140 list_editable = []
141 fields = ['salutation', 'nom', 'prenom', 'courriel', 'afficher_courriel',
142 'fonction', 'date_naissance', 'sousfonction', 'telephone',
143 'adresse_postale', 'genre', 'commentaire',
144
145 'nationalite', 'statut', 'diplome', 'etablissement',
146 'etablissement_autre_nom', 'etablissement_autre_pays',
147 'attestation', 'thematique', 'mots_cles', 'discipline',
148 'theme_recherche', 'groupe_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',
156 'expertises_auf']
157
158 def __init__(self, model, admin_site):
159 super(ChercheurVoirAdmin, self).__init__(model, admin_site)
160 self.readonly_fields = self.fields
161
162
163admin.site.register(ChercheurVoir, ChercheurVoirAdmin)
164
6f8d521e
EMS
165class ChercheurAdminQuerySet(ChercheurQuerySet):
166
167 def filter(self, *args, **kwargs):
168 """Gère des filtres supplémentaires pour l'admin.
169
170 C'est la seule façon que j'ai trouvée de contourner les mécanismes
171 de recherche de l'admin."""
6f8d521e
EMS
172 pays = kwargs.pop('pays', None)
173 region = kwargs.pop('region', None)
15ceabe6 174 nord_sud = kwargs.pop('nord_sud', None)
6f8d521e 175 expert = kwargs.pop('expert', None)
b1d4c7ac 176 qs = self
6f8d521e 177 if pays is not None:
15ceabe6
EMS
178 qs = qs.filter(Q(etablissement__pays=pays) |
179 (Q(etablissement=None) & Q(etablissement_autre_pays=pays)))
6f8d521e 180 elif region is not None:
15ceabe6
EMS
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)))
6f8d521e
EMS
186 if expert is not None:
187 if expert in ['1', 1, True]:
188 qs = qs.exclude(expertises=None)
189 else:
190 qs = qs.filter(expertises=None)
191
192 return super(ChercheurAdminQuerySet, qs).filter(*args, **kwargs)
193
cec3f8db 194
4ef9751d 195class ChercheurGroupeAdmin(admin.ModelAdmin):
e92dbca5 196 list_filter = ('groupe','statut')
61c05759
PP
197 list_display = ('groupe', 'chercheur', 'statut')
198 list_editable = ('statut',)
5cba4157 199 search_fields = ('chercheur__nom', 'chercheur__prenom')
4ef9751d 200
b0db5c3e
PP
201 alphabet_filter = 'chercheur__nom'
202 DEFAULT_ALPHABET = ''
203
1fd4a630
PP
204 actions = ['assigner_cgstatut']
205
b0db5c3e
PP
206
207 def lookup_allowed(self, lookup, value):
208 return lookup in ['chercheur__nom__istartswith'] or \
209 admin.ModelAdmin.lookup_allowed(self, lookup, value)
210
4ef9751d
PP
211 def queryset(self, request):
212 qs = super(ChercheurGroupeAdmin, self).queryset(request)
213
214 if not request.user.is_superuser and not request.user.has_perm('chercheurs.change_chercheurgroupe'):
215 qs = qs.filter(groupe__responsables=request.user)
216
217 return qs
218
219 def has_change_permission(self, request, obj=None):
220
221 if not obj:
222 if request.user.responsable_groupe.count():
223 return True
224 else:
225 if request.user in obj.groupe.responsables.all():
226 return True
227
2094c7e5 228 return super(ChercheurGroupeAdmin, self).has_change_permission(request, obj)
4ef9751d 229
1fd4a630
PP
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'
234
6d5279ff 235
44e07248 236class BaseGroupeAdmin(admin.ModelAdmin):
6d5279ff 237 fieldsets = (
0c0d997c
PP
238 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion',
239 'bulletin', 'page_accueil')}),
6d5279ff 240 (('Responsables'), {'fields': ('responsables',)}),
2094c7e5 241 (('Recherches prédéfinies'), {'fields': ('recherches',)}),
6d5279ff 242 )
cec3f8db 243
0c0d997c
PP
244 class Media:
245 js = ['js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js']
246
734b288c
PP
247 def save_model(self, request, obj, form, change):
248 responsables = form.cleaned_data['responsables']
249 for user in responsables:
250 user.is_staff = True
251 user.save()
252
2094c7e5
PP
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
256
734b288c
PP
257 super(BaseGroupeAdmin, self).save_model(request, obj, form, change)
258
4a7399ee
PP
259 def queryset(self, request):
260 qs = super(BaseGroupeAdmin, self).queryset(request)
261
f522cbdf 262 if not request.user.is_superuser and not request.user.has_perm('chercheurs.change_groupechercheur'):
85f53a92
PP
263 qs = qs.filter(responsables=request.user)
264
265 return qs
4a7399ee
PP
266
267 def has_change_permission(self, request, obj=None, groupe_chercheur=False):
268
269 if not obj:
270 if request.user.responsable_groupe.filter(groupe_chercheur=groupe_chercheur).count():
271 return True
272 else:
273 if request.user in obj.responsables.all():
274 return True
275
276 return super(BaseGroupeAdmin, self).has_change_permission(request, obj)
734b288c 277
2094c7e5
PP
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)
283
284
44e07248 285class GroupeChercheurAdmin(BaseGroupeAdmin):
4a7399ee
PP
286
287 def has_change_permission(self, request, obj=None):
288 return super(GroupeChercheurAdmin, self).has_change_permission(request, obj, groupe_chercheur=True)
289
44e07248
PP
290
291class DomaineRechercheAdmin(BaseGroupeAdmin):
4a7399ee
PP
292
293 def has_change_permission(self, request, obj=None):
294 return super(DomaineRechercheAdmin, self).has_change_permission(request, obj, groupe_chercheur=False)
cec3f8db 295
55ef8558 296admin.site.register(Chercheur, ChercheurAdmin)
cbae0173 297admin.site.register(Publication)
cec3f8db
PP
298admin.site.register(GroupeChercheur, GroupeChercheurAdmin)
299admin.site.register(DomaineRecherche, DomaineRechercheAdmin)
4ef9751d 300admin.site.register(ChercheurGroupe, ChercheurGroupeAdmin)
cbae0173 301