| 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 = 25 |
| 16 | actions = ('remove_from_group', 'export_as_ods', 'export_as_csv') |
| 17 | search_fields = ('nom', 'prenom') |
| 18 | |
| 19 | def lookup_allowed(self, lookup): |
| 20 | return lookup in ['genre', 'statut', 'membre_reseau_institutionnel', |
| 21 | 'membre_instance_auf', 'discipline', 'region', 'pays', |
| 22 | 'groupes', 'nord_sud'] or \ |
| 23 | admin.ModelAdmin.lookup_allowed(self, lookup) |
| 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 export(self, queryset, type): |
| 50 | if queryset.count() == 0: |
| 51 | return None |
| 52 | obj = queryset[0] |
| 53 | headers = ['Nom', 'Prénom', 'Genre', 'Courriel', 'Téléphone', 'Adresse postale', |
| 54 | 'Statut', 'Diplôme', 'Établissement', 'Pays', 'Domaines de recherche', |
| 55 | 'Thèse', 'Directeur', 'Discipline', 'Thèmes de recherche', 'Groupe de recherche', 'Mots-clés', |
| 56 | 'Site web', 'Blog', 'Réseau social', |
| 57 | 'Membre instance AUF', "Sollicité par l'OIF", 'Membre société francophone', |
| 58 | 'Membre instance réseau institutionnel AUF', 'Expertises', 'Solliciter pour expertises', |
| 59 | 'Publications'] |
| 60 | data = [] |
| 61 | for c in queryset: |
| 62 | row = [] |
| 63 | row.append(c.nom) |
| 64 | row.append(c.prenom) |
| 65 | row.append(c.get_genre_display()) |
| 66 | row.append(c.courriel) |
| 67 | row.append(c.telephone) |
| 68 | row.append(c.adresse_postale) |
| 69 | row.append(c.get_statut_display()) |
| 70 | row.append(c.diplome) |
| 71 | row.append(c.nom_etablissement) |
| 72 | row.append(c.pays) |
| 73 | row.append(', '.join(g.nom for g in c.groupes.all())) |
| 74 | try: |
| 75 | t = c.these |
| 76 | row.append('%s, %s, %s, %s pages.' % (t.titre, t.etablissement, t.annee, t.nb_pages)) |
| 77 | row.append(t.directeur) |
| 78 | except These.DoesNotExist: |
| 79 | row.append('') |
| 80 | row.append('') |
| 81 | row.append(c.discipline.nom if c.discipline else '') |
| 82 | row.append(c.theme_recherche) |
| 83 | row.append(c.groupe_recherche) |
| 84 | row.append(c.mots_cles) |
| 85 | row.append(c.url_site_web) |
| 86 | row.append(c.url_blog) |
| 87 | row.append(c.url_reseau_social) |
| 88 | if c.membre_instance_auf: |
| 89 | row.append(', '.join([c.membre_instance_auf_nom, c.membre_instance_auf_fonction, c.membre_instance_auf_dates])) |
| 90 | else: |
| 91 | row.append('') |
| 92 | if c.expert_oif: |
| 93 | row.append(', '.join([c.expert_oif_details, c.expert_oif_dates])) |
| 94 | else: |
| 95 | row.append('') |
| 96 | if c.membre_association_francophone: |
| 97 | row.append(c.membre_association_francophone_details) |
| 98 | else: |
| 99 | row.append('') |
| 100 | if c.membre_reseau_institutionnel: |
| 101 | row.append(', '.join([c.membre_reseau_institutionnel_nom, c.membre_reseau_institutionnel_fonction, c.membre_reseau_institutionnel_dates])) |
| 102 | else: |
| 103 | row.append('') |
| 104 | row.append('; '.join(', '.join([e.nom, e.date, e.organisme_demandeur]) for e in c.expertises.all())) |
| 105 | if c.expertises_auf is None: |
| 106 | row.append('') |
| 107 | else: |
| 108 | row.append('Oui' if c.expertises_auf else 'Non') |
| 109 | row.append('; '.join(p.publication_affichage if p.publication_affichage else |
| 110 | '%s, %s, %s, %s, %s, %s, %s pages.' % |
| 111 | (p.auteurs, p.titre, p.revue, p.annee, p.editeur, p.lieu_edition, p.nb_pages) |
| 112 | for p in c.publications.all())) |
| 113 | data.append([smart_str(x) if x else '' for x in row]) |
| 114 | return exportateur(headers, data, type, filename='chercheurs.%s' % type) |
| 115 | |
| 116 | def export_as_csv(self, request, queryset): |
| 117 | return self.export(queryset, 'csv') |
| 118 | export_as_csv.short_description = 'Export CSV' |
| 119 | |
| 120 | def export_as_ods(self, request, queryset): |
| 121 | return self.export(queryset, 'ods') |
| 122 | export_as_ods.short_description = 'Export ODS' |
| 123 | |
| 124 | class ChercheurAdminQuerySet(ChercheurQuerySet): |
| 125 | |
| 126 | def filter(self, *args, **kwargs): |
| 127 | """Gère des filtres supplémentaires pour l'admin. |
| 128 | |
| 129 | C'est la seule façon que j'ai trouvée de contourner les mécanismes |
| 130 | de recherche de l'admin.""" |
| 131 | qs = self |
| 132 | pays = kwargs.pop('pays', None) |
| 133 | region = kwargs.pop('region', None) |
| 134 | nord_sud = kwargs.pop('nord_sud', None) |
| 135 | expert = kwargs.pop('expert', None) |
| 136 | if pays is not None: |
| 137 | qs = qs.filter(Q(etablissement__pays=pays) | |
| 138 | (Q(etablissement=None) & Q(etablissement_autre_pays=pays))) |
| 139 | elif region is not None: |
| 140 | qs = qs.filter(Q(etablissement__pays__region=region) | |
| 141 | (Q(etablissement=None) & Q(etablissement_autre_pays__region=region))) |
| 142 | elif nord_sud is not None: |
| 143 | qs = qs.filter(Q(etablissement__pays__nord_sud=nord_sud) | |
| 144 | (Q(etablissement=None) & Q(etablissement_autre_pays__nord_sud=nord_sud))) |
| 145 | if expert is not None: |
| 146 | if expert in ['1', 1, True]: |
| 147 | qs = qs.exclude(expertises=None) |
| 148 | else: |
| 149 | qs = qs.filter(expertises=None) |
| 150 | |
| 151 | return super(ChercheurAdminQuerySet, qs).filter(*args, **kwargs) |
| 152 | |
| 153 | admin.site.register(Chercheur, ChercheurAdmin) |
| 154 | admin.site.register(Publication) |
| 155 | admin.site.register(Groupe) |
| 156 | |