Merge branch 'dev' of ssh://git.auf/auf_savoirs_en_partage_django into dev
[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
5b55252d 11from chercheurs.models import Chercheur, Publication, GroupeChercheur, DomaineRecherche, ChercheurGroupe, ChercheurQuerySet, These
2094c7e5 12from savoirs.models import Search
6f8d521e 13
55ef8558 14class ChercheurAdmin(admin.ModelAdmin):
6f8d521e 15 list_filter = ['genre']
b1d4c7ac
PP
16 alphabet_filter = 'nom'
17 alphabet_filter_table = 'chercheurs_personne'
18 DEFAULT_ALPHABET = ''
19
d264c787 20 actions = ('remove_from_group', 'export_as_ods', 'export_as_csv')
62354bdb 21 search_fields = ('nom', 'prenom')
cbae0173 22
ce2fbb36
PP
23 def has_change_permission(self, request, obj=None):
24 if not obj and request.user.has_perm('chercheurs.view_chercheur'):
25 return True
26
27 return super(ChercheurAdmin, self).has_change_permission(request, obj)
28
29 def change_view(self, request, obj=None):
30 if request.user.has_perm('chercheurs.view_chercheur') and \
31 not super(ChercheurAdmin, self).has_change_permission(request, obj):
32 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist'))
33
34 return super(ChercheurAdmin, self).change_view(request, obj)
35
afc30c28 36 def lookup_allowed(self, lookup, value):
6f8d521e
EMS
37 return lookup in ['genre', 'statut', 'membre_reseau_institutionnel',
38 'membre_instance_auf', 'discipline', 'region', 'pays',
b1d4c7ac 39 'groupes', 'nord_sud'] or \
afc30c28 40 admin.ModelAdmin.lookup_allowed(self, lookup, value)
c0d2903e 41
55ef8558
EMS
42 def remove_from_group(self, request, queryset):
43 groupe_id = request.GET.get('groupes__id__exact')
44 chercheur_ids = queryset.values_list('id', flat=True)
45 matches = ChercheurGroupe.objects.filter(groupe=groupe_id, chercheur__in=chercheur_ids)
46 matches.delete()
47 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist') + '?groupes__id__exact=' + groupe_id)
48
49 def get_actions(self, request):
50 actions = super(ChercheurAdmin, self).get_actions(request)
51
52 # Si on filtre par groupe de recherche, offrir d'en retirer les
53 # chercheurs sélectionnés.
54 groupe_id = request.GET.get('groupes__id__exact')
55 if groupe_id:
56 groupe = Groupe.objects.get(id=groupe_id)
57 action_desc = actions['remove_from_group']
e7b9234a 58 actions['remove_from_group'] = (action_desc[0], action_desc[1], u'Retirer du domaine de recherche « %s »' % groupe.nom)
55ef8558
EMS
59 else:
60 del actions['remove_from_group']
61 return actions
62
6f8d521e
EMS
63 def queryset(self, request):
64 return ChercheurAdminQuerySet(Chercheur)
65
ee2ef0e8
EMS
66 def get_object(self, request, object_id):
67 """On doit réimplémenter cette méthode à cause de ce qu'on fait avec "initial" dans la méthode queryset()."""
68 try:
69 return Chercheur.objects.get(id=object_id)
70 except Chercheur.DoesNotExist:
71 return None
72
d264c787
EMS
73 def export(self, queryset, type):
74 if queryset.count() == 0:
75 return None
76 obj = queryset[0]
77 headers = ['Nom', 'Prénom', 'Genre', 'Courriel', 'Téléphone', 'Adresse postale',
78 'Statut', 'Diplôme', 'Établissement', 'Pays', 'Domaines de recherche',
79 'Thèse', 'Directeur', 'Discipline', 'Thèmes de recherche', 'Groupe de recherche', 'Mots-clés',
80 'Site web', 'Blog', 'Réseau social',
81 'Membre instance AUF', "Sollicité par l'OIF", 'Membre société francophone',
82 'Membre instance réseau institutionnel AUF', 'Expertises', 'Solliciter pour expertises',
83 'Publications']
84 data = []
85 for c in queryset:
86 row = []
87 row.append(c.nom)
88 row.append(c.prenom)
89 row.append(c.get_genre_display())
90 row.append(c.courriel)
91 row.append(c.telephone)
92 row.append(c.adresse_postale)
93 row.append(c.get_statut_display())
94 row.append(c.diplome)
95 row.append(c.nom_etablissement)
96 row.append(c.pays)
97 row.append(', '.join(g.nom for g in c.groupes.all()))
98 try:
99 t = c.these
100 row.append('%s, %s, %s, %s pages.' % (t.titre, t.etablissement, t.annee, t.nb_pages))
101 row.append(t.directeur)
102 except These.DoesNotExist:
103 row.append('')
104 row.append('')
105 row.append(c.discipline.nom if c.discipline else '')
106 row.append(c.theme_recherche)
107 row.append(c.groupe_recherche)
108 row.append(c.mots_cles)
109 row.append(c.url_site_web)
110 row.append(c.url_blog)
111 row.append(c.url_reseau_social)
112 if c.membre_instance_auf:
113 row.append(', '.join([c.membre_instance_auf_nom, c.membre_instance_auf_fonction, c.membre_instance_auf_dates]))
114 else:
115 row.append('')
116 if c.expert_oif:
117 row.append(', '.join([c.expert_oif_details, c.expert_oif_dates]))
118 else:
119 row.append('')
120 if c.membre_association_francophone:
121 row.append(c.membre_association_francophone_details)
122 else:
123 row.append('')
124 if c.membre_reseau_institutionnel:
125 row.append(', '.join([c.membre_reseau_institutionnel_nom, c.membre_reseau_institutionnel_fonction, c.membre_reseau_institutionnel_dates]))
126 else:
127 row.append('')
128 row.append('; '.join(', '.join([e.nom, e.date, e.organisme_demandeur]) for e in c.expertises.all()))
129 if c.expertises_auf is None:
130 row.append('')
131 else:
132 row.append('Oui' if c.expertises_auf else 'Non')
133 row.append('; '.join(p.publication_affichage if p.publication_affichage else
134 '%s, %s, %s, %s, %s, %s, %s pages.' %
135 (p.auteurs, p.titre, p.revue, p.annee, p.editeur, p.lieu_edition, p.nb_pages)
136 for p in c.publications.all()))
137 data.append([smart_str(x) if x else '' for x in row])
138 return exportateur(headers, data, type, filename='chercheurs.%s' % type)
139
140 def export_as_csv(self, request, queryset):
141 return self.export(queryset, 'csv')
142 export_as_csv.short_description = 'Export CSV'
143
144 def export_as_ods(self, request, queryset):
145 return self.export(queryset, 'ods')
146 export_as_ods.short_description = 'Export ODS'
147
6f8d521e
EMS
148class ChercheurAdminQuerySet(ChercheurQuerySet):
149
150 def filter(self, *args, **kwargs):
151 """Gère des filtres supplémentaires pour l'admin.
152
153 C'est la seule façon que j'ai trouvée de contourner les mécanismes
154 de recherche de l'admin."""
6f8d521e
EMS
155 pays = kwargs.pop('pays', None)
156 region = kwargs.pop('region', None)
15ceabe6 157 nord_sud = kwargs.pop('nord_sud', None)
6f8d521e 158 expert = kwargs.pop('expert', None)
b1d4c7ac 159 qs = self
6f8d521e 160 if pays is not None:
15ceabe6
EMS
161 qs = qs.filter(Q(etablissement__pays=pays) |
162 (Q(etablissement=None) & Q(etablissement_autre_pays=pays)))
6f8d521e 163 elif region is not None:
15ceabe6
EMS
164 qs = qs.filter(Q(etablissement__pays__region=region) |
165 (Q(etablissement=None) & Q(etablissement_autre_pays__region=region)))
166 elif nord_sud is not None:
167 qs = qs.filter(Q(etablissement__pays__nord_sud=nord_sud) |
168 (Q(etablissement=None) & Q(etablissement_autre_pays__nord_sud=nord_sud)))
6f8d521e
EMS
169 if expert is not None:
170 if expert in ['1', 1, True]:
171 qs = qs.exclude(expertises=None)
172 else:
173 qs = qs.filter(expertises=None)
174
175 return super(ChercheurAdminQuerySet, qs).filter(*args, **kwargs)
176
cec3f8db 177
4ef9751d
PP
178class ChercheurGroupeAdmin(admin.ModelAdmin):
179 list_filter = ('groupe',)
180 list_display = ('groupe', 'chercheur', 'actif')
181 list_editable = ('actif',)
182
183 def queryset(self, request):
184 qs = super(ChercheurGroupeAdmin, self).queryset(request)
185
186 if not request.user.is_superuser and not request.user.has_perm('chercheurs.change_chercheurgroupe'):
187 qs = qs.filter(groupe__responsables=request.user)
188
189 return qs
190
191 def has_change_permission(self, request, obj=None):
192
193 if not obj:
194 if request.user.responsable_groupe.count():
195 return True
196 else:
197 if request.user in obj.groupe.responsables.all():
198 return True
199
2094c7e5 200 return super(ChercheurGroupeAdmin, self).has_change_permission(request, obj)
4ef9751d 201
6d5279ff
PP
202class MemberInline(admin.TabularInline):
203 model = ChercheurGroupe
204
205
44e07248 206class BaseGroupeAdmin(admin.ModelAdmin):
cec3f8db 207 filter_horizontal = ('responsables',)
6d5279ff 208 fieldsets = (
0c0d997c
PP
209 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion',
210 'bulletin', 'page_accueil')}),
6d5279ff 211 (('Responsables'), {'fields': ('responsables',)}),
2094c7e5 212 (('Recherches prédéfinies'), {'fields': ('recherches',)}),
6d5279ff
PP
213 )
214 inlines = [
215 MemberInline,
216 ]
cec3f8db 217
0c0d997c
PP
218 class Media:
219 js = ['js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js']
220
734b288c
PP
221 def save_model(self, request, obj, form, change):
222 responsables = form.cleaned_data['responsables']
223 for user in responsables:
224 user.is_staff = True
225 user.save()
226
2094c7e5
PP
227 if not request.user.is_superuser:
228 recherches = Search.objects.exclude(user=request.user)
229 form.cleaned_data['recherches'] = form.cleaned_data['recherches'] | recherches
230
734b288c
PP
231 super(BaseGroupeAdmin, self).save_model(request, obj, form, change)
232
4a7399ee
PP
233 def queryset(self, request):
234 qs = super(BaseGroupeAdmin, self).queryset(request)
235
f522cbdf 236 if not request.user.is_superuser and not request.user.has_perm('chercheurs.change_groupechercheur'):
85f53a92
PP
237 qs = qs.filter(responsables=request.user)
238
239 return qs
4a7399ee
PP
240
241 def has_change_permission(self, request, obj=None, groupe_chercheur=False):
242
243 if not obj:
244 if request.user.responsable_groupe.filter(groupe_chercheur=groupe_chercheur).count():
245 return True
246 else:
247 if request.user in obj.responsables.all():
248 return True
249
250 return super(BaseGroupeAdmin, self).has_change_permission(request, obj)
734b288c 251
2094c7e5
PP
252 def formfield_for_manytomany(self, db_field, request, **kwargs):
253 if db_field.name == "recherches" and not request.user.is_superuser:
254 kwargs["queryset"] = Search.objects.filter(user=request.user)
255 return db_field.formfield(**kwargs)
256 return super(BaseGroupeAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
257
258
44e07248 259class GroupeChercheurAdmin(BaseGroupeAdmin):
4a7399ee
PP
260
261 def has_change_permission(self, request, obj=None):
262 return super(GroupeChercheurAdmin, self).has_change_permission(request, obj, groupe_chercheur=True)
263
44e07248
PP
264
265class DomaineRechercheAdmin(BaseGroupeAdmin):
4a7399ee
PP
266
267 def has_change_permission(self, request, obj=None):
268 return super(DomaineRechercheAdmin, self).has_change_permission(request, obj, groupe_chercheur=False)
cec3f8db 269
55ef8558 270admin.site.register(Chercheur, ChercheurAdmin)
cbae0173 271admin.site.register(Publication)
cec3f8db
PP
272admin.site.register(GroupeChercheur, GroupeChercheurAdmin)
273admin.site.register(DomaineRecherche, DomaineRechercheAdmin)
4ef9751d 274admin.site.register(ChercheurGroupe, ChercheurGroupeAdmin)
cbae0173 275