Paginer les chercheurs par leur initiale.
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / admin.py
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
10
11 from chercheurs.models import Chercheur, Publication, Groupe, ChercheurGroupe, ChercheurQuerySet, These
12
13 class ChercheurAdmin(admin.ModelAdmin):
14 list_filter = ['genre']
15 list_per_page = 9999
16 actions = ('remove_from_group', 'export_as_ods', 'export_as_csv')
17 search_fields = ('nom', 'prenom')
18
19 def lookup_allowed(self, lookup, value):
20 return lookup in ['genre', 'statut', 'membre_reseau_institutionnel',
21 'membre_instance_auf', 'discipline', 'region', 'pays',
22 'groupes', 'nord_sud', 'initial'] or \
23 admin.ModelAdmin.lookup_allowed(self, lookup, value)
24
25 def remove_from_group(self, request, queryset):
26 groupe_id = request.GET.get('groupes__id__exact')
27 chercheur_ids = queryset.values_list('id', flat=True)
28 matches = ChercheurGroupe.objects.filter(groupe=groupe_id, chercheur__in=chercheur_ids)
29 matches.delete()
30 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist') + '?groupes__id__exact=' + groupe_id)
31
32 def get_actions(self, request):
33 actions = super(ChercheurAdmin, self).get_actions(request)
34
35 # Si on filtre par groupe de recherche, offrir d'en retirer les
36 # chercheurs sélectionnés.
37 groupe_id = request.GET.get('groupes__id__exact')
38 if groupe_id:
39 groupe = Groupe.objects.get(id=groupe_id)
40 action_desc = actions['remove_from_group']
41 actions['remove_from_group'] = (action_desc[0], action_desc[1], u'Retirer du domaine de recherche « %s »' % groupe.nom)
42 else:
43 del actions['remove_from_group']
44 return actions
45
46 def queryset(self, request):
47 return ChercheurAdminQuerySet(Chercheur)
48
49 def changelist_view(self, request, extra_context=None):
50 initials = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
51 current_initial = request.GET.get('initial', 'A')
52 return super(ChercheurAdmin, self).changelist_view(request, extra_context={
53 'initials': initials,
54 'current_initial': current_initial
55 })
56
57 def export(self, queryset, type):
58 if queryset.count() == 0:
59 return None
60 obj = queryset[0]
61 headers = ['Nom', 'Prénom', 'Genre', 'Courriel', 'Téléphone', 'Adresse postale',
62 'Statut', 'Diplôme', 'Établissement', 'Pays', 'Domaines de recherche',
63 'Thèse', 'Directeur', 'Discipline', 'Thèmes de recherche', 'Groupe de recherche', 'Mots-clés',
64 'Site web', 'Blog', 'Réseau social',
65 'Membre instance AUF', "Sollicité par l'OIF", 'Membre société francophone',
66 'Membre instance réseau institutionnel AUF', 'Expertises', 'Solliciter pour expertises',
67 'Publications']
68 data = []
69 for c in queryset:
70 row = []
71 row.append(c.nom)
72 row.append(c.prenom)
73 row.append(c.get_genre_display())
74 row.append(c.courriel)
75 row.append(c.telephone)
76 row.append(c.adresse_postale)
77 row.append(c.get_statut_display())
78 row.append(c.diplome)
79 row.append(c.nom_etablissement)
80 row.append(c.pays)
81 row.append(', '.join(g.nom for g in c.groupes.all()))
82 try:
83 t = c.these
84 row.append('%s, %s, %s, %s pages.' % (t.titre, t.etablissement, t.annee, t.nb_pages))
85 row.append(t.directeur)
86 except These.DoesNotExist:
87 row.append('')
88 row.append('')
89 row.append(c.discipline.nom if c.discipline else '')
90 row.append(c.theme_recherche)
91 row.append(c.groupe_recherche)
92 row.append(c.mots_cles)
93 row.append(c.url_site_web)
94 row.append(c.url_blog)
95 row.append(c.url_reseau_social)
96 if c.membre_instance_auf:
97 row.append(', '.join([c.membre_instance_auf_nom, c.membre_instance_auf_fonction, c.membre_instance_auf_dates]))
98 else:
99 row.append('')
100 if c.expert_oif:
101 row.append(', '.join([c.expert_oif_details, c.expert_oif_dates]))
102 else:
103 row.append('')
104 if c.membre_association_francophone:
105 row.append(c.membre_association_francophone_details)
106 else:
107 row.append('')
108 if c.membre_reseau_institutionnel:
109 row.append(', '.join([c.membre_reseau_institutionnel_nom, c.membre_reseau_institutionnel_fonction, c.membre_reseau_institutionnel_dates]))
110 else:
111 row.append('')
112 row.append('; '.join(', '.join([e.nom, e.date, e.organisme_demandeur]) for e in c.expertises.all()))
113 if c.expertises_auf is None:
114 row.append('')
115 else:
116 row.append('Oui' if c.expertises_auf else 'Non')
117 row.append('; '.join(p.publication_affichage if p.publication_affichage else
118 '%s, %s, %s, %s, %s, %s, %s pages.' %
119 (p.auteurs, p.titre, p.revue, p.annee, p.editeur, p.lieu_edition, p.nb_pages)
120 for p in c.publications.all()))
121 data.append([smart_str(x) if x else '' for x in row])
122 return exportateur(headers, data, type, filename='chercheurs.%s' % type)
123
124 def export_as_csv(self, request, queryset):
125 return self.export(queryset, 'csv')
126 export_as_csv.short_description = 'Export CSV'
127
128 def export_as_ods(self, request, queryset):
129 return self.export(queryset, 'ods')
130 export_as_ods.short_description = 'Export ODS'
131
132 class ChercheurAdminQuerySet(ChercheurQuerySet):
133
134 def filter(self, *args, **kwargs):
135 """Gère des filtres supplémentaires pour l'admin.
136
137 C'est la seule façon que j'ai trouvée de contourner les mécanismes
138 de recherche de l'admin."""
139 pays = kwargs.pop('pays', None)
140 region = kwargs.pop('region', None)
141 nord_sud = kwargs.pop('nord_sud', None)
142 expert = kwargs.pop('expert', None)
143 initial = kwargs.pop('initial', 'A')
144 qs = super(ChercheurAdminQuerySet, self).filter(nom__istartswith=initial)
145 if pays is not None:
146 qs = qs.filter(Q(etablissement__pays=pays) |
147 (Q(etablissement=None) & Q(etablissement_autre_pays=pays)))
148 elif region is not None:
149 qs = qs.filter(Q(etablissement__pays__region=region) |
150 (Q(etablissement=None) & Q(etablissement_autre_pays__region=region)))
151 elif nord_sud is not None:
152 qs = qs.filter(Q(etablissement__pays__nord_sud=nord_sud) |
153 (Q(etablissement=None) & Q(etablissement_autre_pays__nord_sud=nord_sud)))
154 if expert is not None:
155 if expert in ['1', 1, True]:
156 qs = qs.exclude(expertises=None)
157 else:
158 qs = qs.filter(expertises=None)
159
160 return super(ChercheurAdminQuerySet, qs).filter(*args, **kwargs)
161
162 admin.site.register(Chercheur, ChercheurAdmin)
163 admin.site.register(Publication)
164 admin.site.register(Groupe)
165