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
, Publication
, GroupeChercheur
, DomaineRecherche
, ChercheurGroupe
, ChercheurQuerySet
, These
13 class ChercheurAdmin(admin
.ModelAdmin
):
14 list_filter
= ['genre']
15 alphabet_filter
= 'nom'
16 alphabet_filter_table
= 'chercheurs_personne'
19 actions
= ('remove_from_group', 'export_as_ods', 'export_as_csv')
20 search_fields
= ('nom', 'prenom')
22 def has_change_permission(self
, request
, obj
=None):
23 if not obj
and request
.user
.has_perm('chercheurs.view_chercheur'):
26 return super(ChercheurAdmin
, self
).has_change_permission(request
, obj
)
28 def change_view(self
, request
, obj
=None):
29 if request
.user
.has_perm('chercheurs.view_chercheur') and \
30 not super(ChercheurAdmin
, self
).has_change_permission(request
, obj
):
31 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist'))
33 return super(ChercheurAdmin
, self
).change_view(request
, obj
)
35 def lookup_allowed(self
, lookup
, value
):
36 return lookup
in ['genre', 'statut', 'membre_reseau_institutionnel',
37 'membre_instance_auf', 'discipline', 'region', 'pays',
38 'groupes', 'nord_sud'] or \
39 admin
.ModelAdmin
.lookup_allowed(self
, lookup
, value
)
41 def remove_from_group(self
, request
, queryset
):
42 groupe_id
= request
.GET
.get('groupes__id__exact')
43 chercheur_ids
= queryset
.values_list('id', flat
=True)
44 matches
= ChercheurGroupe
.objects
.filter(groupe
=groupe_id
, chercheur__in
=chercheur_ids
)
46 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist') + '?groupes__id__exact=' + groupe_id
)
48 def get_actions(self
, request
):
49 actions
= super(ChercheurAdmin
, self
).get_actions(request
)
51 # Si on filtre par groupe de recherche, offrir d'en retirer les
52 # chercheurs sélectionnés.
53 groupe_id
= request
.GET
.get('groupes__id__exact')
55 groupe
= Groupe
.objects
.get(id=groupe_id
)
56 action_desc
= actions
['remove_from_group']
57 actions
['remove_from_group'] = (action_desc
[0], action_desc
[1], u
'Retirer du domaine de recherche « %s »' % groupe
.nom
)
59 del actions
['remove_from_group']
62 def queryset(self
, request
):
63 return ChercheurAdminQuerySet(Chercheur
)
65 def get_object(self
, request
, object_id
):
66 """On doit réimplémenter cette méthode à cause de ce qu'on fait avec "initial" dans la méthode queryset()."""
68 return Chercheur
.objects
.get(id=object_id
)
69 except Chercheur
.DoesNotExist
:
72 def export(self
, queryset
, type):
73 if queryset
.count() == 0:
76 headers
= ['Nom', 'Prénom', 'Genre', 'Courriel', 'Téléphone', 'Adresse postale',
77 'Statut', 'Diplôme', 'Établissement', 'Pays', 'Domaines de recherche',
78 'Thèse', 'Directeur', 'Discipline', 'Thèmes de recherche', 'Groupe de recherche', 'Mots-clés',
79 'Site web', 'Blog', 'Réseau social',
80 'Membre instance AUF', "Sollicité par l'OIF", 'Membre société francophone',
81 'Membre instance réseau institutionnel AUF', 'Expertises', 'Solliciter pour expertises',
88 row
.append(c
.get_genre_display())
89 row
.append(c
.courriel
)
90 row
.append(c
.telephone
)
91 row
.append(c
.adresse_postale
)
92 row
.append(c
.get_statut_display())
94 row
.append(c
.nom_etablissement
)
96 row
.append(', '.join(g
.nom
for g
in c
.groupes
.all()))
99 row
.append('%s, %s, %s, %s pages.' % (t
.titre
, t
.etablissement
, t
.annee
, t
.nb_pages
))
100 row
.append(t
.directeur
)
101 except These
.DoesNotExist
:
104 row
.append(c
.discipline
.nom
if c
.discipline
else '')
105 row
.append(c
.theme_recherche
)
106 row
.append(c
.groupe_recherche
)
107 row
.append(c
.mots_cles
)
108 row
.append(c
.url_site_web
)
109 row
.append(c
.url_blog
)
110 row
.append(c
.url_reseau_social
)
111 if c
.membre_instance_auf
:
112 row
.append(', '.join([c
.membre_instance_auf_nom
, c
.membre_instance_auf_fonction
, c
.membre_instance_auf_dates
]))
116 row
.append(', '.join([c
.expert_oif_details
, c
.expert_oif_dates
]))
119 if c
.membre_association_francophone
:
120 row
.append(c
.membre_association_francophone_details
)
123 if c
.membre_reseau_institutionnel
:
124 row
.append(', '.join([c
.membre_reseau_institutionnel_nom
, c
.membre_reseau_institutionnel_fonction
, c
.membre_reseau_institutionnel_dates
]))
127 row
.append('; '.join(', '.join([e
.nom
, e
.date
, e
.organisme_demandeur
]) for e
in c
.expertises
.all()))
128 if c
.expertises_auf
is None:
131 row
.append('Oui' if c
.expertises_auf
else 'Non')
132 row
.append('; '.join(p
.publication_affichage
if p
.publication_affichage
else
133 '%s, %s, %s, %s, %s, %s, %s pages.' %
134 (p
.auteurs
, p
.titre
, p
.revue
, p
.annee
, p
.editeur
, p
.lieu_edition
, p
.nb_pages
)
135 for p
in c
.publications
.all()))
136 data
.append([smart_str(x
) if x
else '' for x
in row
])
137 return exportateur(headers
, data
, type, filename
='chercheurs.%s' % type)
139 def export_as_csv(self
, request
, queryset
):
140 return self
.export(queryset
, 'csv')
141 export_as_csv
.short_description
= 'Export CSV'
143 def export_as_ods(self
, request
, queryset
):
144 return self
.export(queryset
, 'ods')
145 export_as_ods
.short_description
= 'Export ODS'
147 class ChercheurAdminQuerySet(ChercheurQuerySet
):
149 def filter(self
, *args
, **kwargs
):
150 """Gère des filtres supplémentaires pour l'admin.
152 C'est la seule façon que j'ai trouvée de contourner les mécanismes
153 de recherche de l'admin."""
154 pays
= kwargs
.pop('pays', None)
155 region
= kwargs
.pop('region', None)
156 nord_sud
= kwargs
.pop('nord_sud', None)
157 expert
= kwargs
.pop('expert', None)
160 qs
= qs
.filter(Q(etablissement__pays
=pays
) |
161 (Q(etablissement
=None) & Q(etablissement_autre_pays
=pays
)))
162 elif region
is not None:
163 qs
= qs
.filter(Q(etablissement__pays__region
=region
) |
164 (Q(etablissement
=None) & Q(etablissement_autre_pays__region
=region
)))
165 elif nord_sud
is not None:
166 qs
= qs
.filter(Q(etablissement__pays__nord_sud
=nord_sud
) |
167 (Q(etablissement
=None) & Q(etablissement_autre_pays__nord_sud
=nord_sud
)))
168 if expert
is not None:
169 if expert
in ['1', 1, True]:
170 qs
= qs
.exclude(expertises
=None)
172 qs
= qs
.filter(expertises
=None)
174 return super(ChercheurAdminQuerySet
, qs
).filter(*args
, **kwargs
)
177 class MemberInline(admin
.TabularInline
):
178 model
= ChercheurGroupe
181 class GroupeChercheurAdmin(admin
.ModelAdmin
):
182 filter_horizontal
= ('responsables',)
184 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion', 'bulletin')}),
185 (('Responsables'), {'fields': ('responsables',)}),
191 class DomaineRechercheAdmin(admin
.ModelAdmin
):
192 filter_horizontal
= ('responsables',)
194 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion', 'bulletin')}),
195 (('Responsables'), {'fields': ('responsables',)}),
201 admin
.site
.register(Chercheur
, ChercheurAdmin
)
202 admin
.site
.register(Publication
)
203 admin
.site
.register(GroupeChercheur
, GroupeChercheurAdmin
)
204 admin
.site
.register(DomaineRecherche
, DomaineRechercheAdmin
)