7ad941a40b0684743d5ae17ad38640f711c7538d
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / admin.py
1 # -*- coding: utf-8 -*-
2 from django.db.models import Q
3 from django.contrib import admin
4 from django.core.urlresolvers import reverse as url
5 from django.http import HttpResponseRedirect
6 from django.contrib.auth.models import User
7
8 from chercheurs.models import Chercheur, ChercheurVoir, Publication, \
9 GroupeChercheur, DomaineRecherche, \
10 AdhesionGroupe, ChercheurQuerySet, \
11 AdhesionCommunaute, AdhesionDomaineRecherche, \
12 Groupe, Message
13
14 from chercheurs.utils import export
15 from savoirs.models import Search
16
17
18 class ChercheurAdmin(admin.ModelAdmin):
19 list_filter = ['genre']
20 alphabet_filter = 'nom'
21 alphabet_filter_table = 'chercheurs_personne'
22 DEFAULT_ALPHABET = ''
23
24 actions = ('remove_from_group', 'export_as_ods', 'export_as_csv')
25 search_fields = ('nom', 'prenom')
26
27 exclude = ('user',)
28
29 def lookup_allowed(self, lookup, value):
30 return lookup in ['genre', 'statut', 'membre_reseau_institutionnel',
31 'membre_instance_auf', 'discipline', 'region',
32 'pays', 'groupes', 'nord_sud'] or \
33 admin.ModelAdmin.lookup_allowed(self, lookup, value)
34
35 def remove_from_group(self, request, queryset):
36 groupe_id = request.GET.get('groupes__id__exact')
37 chercheur_ids = queryset.values_list('id', flat=True)
38 matches = AdhesionGroupe.objects.filter(
39 groupe=groupe_id, chercheur__in=chercheur_ids
40 )
41 matches.delete()
42 return HttpResponseRedirect(
43 url('admin:chercheurs_chercheur_changelist') +
44 '?groupes__id__exact=' + groupe_id
45 )
46
47 def get_actions(self, request):
48 actions = super(ChercheurAdmin, self).get_actions(request)
49
50 # Si on filtre par groupes, offrir d'en retirer les
51 # chercheurs sélectionnés.
52 groupe_id = request.GET.get('groupes__id__exact')
53 if groupe_id:
54 groupe = Groupe.objects.get(id=groupe_id)
55 action_desc = actions['remove_from_group']
56 actions['remove_from_group'] = (
57 action_desc[0],
58 action_desc[1],
59 u'Retirer du domaine de recherche « %s »' % groupe.nom
60 )
61 else:
62 del actions['remove_from_group']
63 return actions
64
65 def queryset(self, request):
66 return ChercheurAdminQuerySet(Chercheur).filter(actif=True)
67
68 def get_object(self, request, object_id):
69 """
70 On doit réimplémenter cette méthode à cause de ce qu'on fait avec
71 ``initial`` dans la méthode queryset().
72 """
73 try:
74 return Chercheur.objects.get(id=object_id)
75 except Chercheur.DoesNotExist:
76 return None
77
78 def has_add_permission(self, request, obj=None):
79 return False
80
81 def export_as_csv(self, request, queryset):
82 return export(queryset, 'csv')
83 export_as_csv.short_description = 'Export CSV'
84
85 def export_as_ods(self, request, queryset):
86 return export(queryset, 'ods')
87 export_as_ods.short_description = 'Export ODS'
88
89
90 class ChercheurVoirAdmin(ChercheurAdmin):
91
92 list_editable = []
93 fields = ['salutation', 'nom', 'prenom', 'courriel',
94 'afficher_courriel', 'fonction', 'date_naissance',
95 'sousfonction', 'telephone', 'adresse_postale', 'genre',
96 'commentaire', 'nationalite', 'statut', 'diplome',
97 'etablissement', 'etablissement_autre_nom',
98 'etablissement_autre_pays', 'attestation', 'thematique',
99 'mots_cles', 'discipline', 'theme_recherche',
100 'equipe_recherche', 'url_site_web', 'url_blog',
101 'url_reseau_social', 'membre_instance_auf',
102 'membre_instance_auf_nom', 'membre_instance_auf_fonction',
103 'membre_instance_auf_dates', 'expert_oif',
104 'expert_oif_details', 'expert_oif_dates',
105 'membre_association_francophone',
106 'membre_association_francophone_details',
107 'membre_reseau_institutionnel',
108 'membre_reseau_institutionnel_nom',
109 'membre_reseau_institutionnel_fonction',
110 'membre_reseau_institutionnel_dates', 'expertises_auf']
111
112 def __init__(self, model, admin_site):
113 super(ChercheurVoirAdmin, self).__init__(model, admin_site)
114 self.readonly_fields = self.fields
115
116 admin.site.register(ChercheurVoir, ChercheurVoirAdmin)
117
118
119 class ChercheurAdminQuerySet(ChercheurQuerySet):
120
121 def delete(self):
122 self.update(actif=False)
123
124 def filter(self, *args, **kwargs):
125 """Gère des filtres supplémentaires pour l'admin.
126
127 C'est la seule façon que j'ai trouvée de contourner les mécanismes
128 de recherche de l'admin."""
129 pays = kwargs.pop('pays', None)
130 region = kwargs.pop('region', None)
131 nord_sud = kwargs.pop('nord_sud', None)
132 expert = kwargs.pop('expert', None)
133 qs = self
134 if pays is not None:
135 qs = qs.filter(
136 Q(etablissement__pays=pays) |
137 (Q(etablissement=None) & Q(etablissement_autre_pays=pays))
138 )
139 elif region is not None:
140 qs = qs.filter(
141 Q(etablissement__pays__region=region) |
142 (Q(etablissement=None) &
143 Q(etablissement_autre_pays__region=region))
144 )
145 elif nord_sud is not None:
146 qs = qs.filter(
147 Q(etablissement__pays__nord_sud=nord_sud) |
148 (Q(etablissement=None) &
149 Q(etablissement_autre_pays__nord_sud=nord_sud))
150 )
151 if expert is not None:
152 if expert in ['1', 1, True]:
153 qs = qs.exclude(expertises=None)
154 else:
155 qs = qs.filter(expertises=None)
156
157 return super(ChercheurAdminQuerySet, qs).filter(*args, **kwargs)
158
159
160 class AdhesionGroupeAdmin(admin.ModelAdmin):
161 list_filter = ('groupe', 'statut')
162 list_display = ('groupe', 'chercheur', 'statut')
163 list_editable = ('statut',)
164 search_fields = ('chercheur__nom', 'chercheur__prenom')
165
166 alphabet_filter = 'chercheur__nom'
167 DEFAULT_ALPHABET = ''
168
169 actions = ['assigner_cgstatut']
170
171 def lookup_allowed(self, lookup, value):
172 return lookup in ['chercheur__nom__istartswith'] or \
173 admin.ModelAdmin.lookup_allowed(self, lookup, value)
174
175 def queryset(self, request):
176 qs = super(AdhesionGroupeAdmin, self).queryset(request)
177
178 if not request.user.is_superuser \
179 and not request.user.has_perm('chercheurs.change_adhesiongroupe'):
180 qs = qs.filter(groupe__responsables=request.user)
181
182 return qs
183
184 def has_change_permission(self, request, obj=None):
185
186 if not obj:
187 if request.user.responsable_groupe.count():
188 return True
189 else:
190 if request.user in obj.groupe.responsables.all():
191 return True
192
193 return super(AdhesionGroupeAdmin, self) \
194 .has_change_permission(request, obj)
195
196 def assigner_cgstatut(self, request, queryset):
197 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
198 return HttpResponseRedirect(
199 "/admin/assigner_%s?ids=%s" % ('cgstatut', ",".join(selected))
200 )
201 assigner_cgstatut.short_description = u'Assigner un statut'
202
203
204 class AdhesionCommunauteAdmin(AdhesionGroupeAdmin):
205 pass
206
207
208 class AdhesionDomaineRechercheAdmin(AdhesionGroupeAdmin):
209 pass
210
211
212 class BaseGroupeAdmin(admin.ModelAdmin):
213 search_fields = ['nom']
214 fieldsets = (
215 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion',
216 'bulletin', 'page_accueil')}),
217 (('Gestionnaire de communauté'), {'fields': ('responsables',)}),
218 (('Recherches prédéfinies'), {'fields': ('recherches',)}),
219 )
220
221 class Media:
222 js = ['js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js']
223
224 def save_model(self, request, obj, form, change):
225 responsables = form.cleaned_data['responsables']
226 for user in responsables:
227 user.is_staff = True
228 user.save()
229
230 if not request.user.is_superuser:
231 recherches = obj.recherches.exclude(user=request.user)
232 form.cleaned_data['recherches'] = \
233 set(form.cleaned_data['recherches']) | set(recherches)
234
235 super(BaseGroupeAdmin, self).save_model(request, obj, form, change)
236
237 def queryset(self, request):
238 qs = super(BaseGroupeAdmin, self).queryset(request)
239
240 if not request.user.is_superuser \
241 and not request.user.has_perm('chercheurs.change_groupechercheur'):
242 qs = qs.filter(responsables=request.user)
243
244 return qs
245
246 def has_change_permission(self, request, obj=None, groupe_chercheur=False):
247
248 if not obj:
249 if request.user.responsable_groupe \
250 .filter(groupe_chercheur=groupe_chercheur).count():
251 return True
252 else:
253 if request.user in obj.responsables.all():
254 return True
255
256 return super(BaseGroupeAdmin, self).has_change_permission(request, obj)
257
258 def formfield_for_manytomany(self, db_field, request, **kwargs):
259 if db_field.name == "recherches" and not request.user.is_superuser:
260 kwargs["queryset"] = Search.objects.filter(user=request.user)
261 return db_field.formfield(**kwargs)
262
263 if db_field.name == "responsables":
264 kwargs["queryset"] = User.objects.all().order_by('username')
265 return db_field.formfield(**kwargs)
266
267 return super(BaseGroupeAdmin, self).formfield_for_manytomany(
268 db_field, request, **kwargs
269 )
270
271
272 class GroupeChercheurAdmin(BaseGroupeAdmin):
273
274 def has_change_permission(self, request, obj=None):
275 return super(GroupeChercheurAdmin, self) \
276 .has_change_permission(request, obj, groupe_chercheur=True)
277
278
279 class DomaineRechercheAdmin(BaseGroupeAdmin):
280
281 def has_change_permission(self, request, obj=None):
282 return super(DomaineRechercheAdmin, self) \
283 .has_change_permission(request, obj, groupe_chercheur=False)
284
285
286 class MessageAdmin(admin.ModelAdmin):
287 list_filter = ('groupe',)
288
289
290 class PublicationAdmin(admin.ModelAdmin):
291 search_fields = ('auteurs', 'titre', 'revue', 'editeur')
292
293
294 admin.site.register(Chercheur, ChercheurAdmin)
295 admin.site.register(Publication, PublicationAdmin)
296 admin.site.register(GroupeChercheur, GroupeChercheurAdmin)
297 admin.site.register(DomaineRecherche, DomaineRechercheAdmin)
298 admin.site.register(AdhesionCommunaute, AdhesionCommunauteAdmin)
299 admin.site.register(AdhesionDomaineRecherche, AdhesionDomaineRechercheAdmin)
300 admin.site.register(Message, MessageAdmin)