Commit | Line | Data |
---|---|---|
6f8d521e | 1 | # -*- coding: utf-8 -*- |
cbae0173 | 2 | from django.db import models |
6f8d521e | 3 | from django.db.models import Q |
cbae0173 | 4 | from django.contrib import admin |
55ef8558 EMS |
5 | from django.core.urlresolvers import reverse as url |
6 | from django.forms.models import BaseInlineFormSet | |
7 | from django.http import HttpResponseRedirect | |
d264c787 EMS |
8 | from django.utils.encoding import smart_str |
9 | from django_exportateur.exportateur import exportateur | |
cbae0173 | 10 | |
81fe476e PP |
11 | from chercheurs.models import Chercheur, ChercheurVoir, Publication, \ |
12 | GroupeChercheur, DomaineRecherche, \ | |
13 | ChercheurGroupe, ChercheurQuerySet, These | |
2094c7e5 | 14 | from savoirs.models import Search |
6f8d521e | 15 | |
55ef8558 | 16 | class 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 | |
138 | class 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 | ||
163 | admin.site.register(ChercheurVoir, ChercheurVoirAdmin) | |
164 | ||
6f8d521e EMS |
165 | class 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 | 195 | class 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 | 236 | class 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 | 285 | class 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 | |
291 | class 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 | 296 | admin.site.register(Chercheur, ChercheurAdmin) |
cbae0173 | 297 | admin.site.register(Publication) |
cec3f8db PP |
298 | admin.site.register(GroupeChercheur, GroupeChercheurAdmin) |
299 | admin.site.register(DomaineRecherche, DomaineRechercheAdmin) | |
4ef9751d | 300 | admin.site.register(ChercheurGroupe, ChercheurGroupeAdmin) |
cbae0173 | 301 |