Légères améliorations à l'interface d'admin pour les ressources.
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / admin.py
CommitLineData
6ef8ead4 1# -*- encoding: utf-8 -*-
23b5b3d5 2import re
e3c3296e 3
264a3210 4from django.core.urlresolvers import reverse as url
6a6986bc 5from django.db import models
6ef8ead4 6from django.contrib import admin
6d885e0c 7from django.contrib.auth.admin import UserAdmin
8from django.contrib.auth.models import User
6a6986bc 9from django.contrib.admin.filterspecs import RelatedFilterSpec, FilterSpec
23b5b3d5 10from django.utils.safestring import mark_safe
6a6986bc 11from django.utils.translation import ugettext as _
12from django.utils.encoding import smart_unicode, iri_to_uri
e3c3296e 13from django.http import HttpResponseRedirect
14
6d885e0c 15from models import SourceActualite, Actualite, Discipline, Evenement, Record, ListSet, HarvestLog, Profile
23b5b3d5 16from savoirs.globals import META
6ef8ead4 17
79c398f6 18admin.site.register(SourceActualite)
6ef8ead4 19
6a6986bc 20class ListSetFilterSpec(RelatedFilterSpec):
21 """
22 Filtre custom automatiquement lié à un field nommé 'listsets'. Il a pour but de s'afficher
23 lorsqu'un server a déjà été présélectionné. Dans ce cas, il affiche une liste qui contient les
24 listsets de ce server.
25 """
26 def __init__(self, f, request, params, model, model_admin):
27 super(ListSetFilterSpec, self).__init__(f, request, params, model, model_admin)
28 self.server_name = request.GET.get('server', None)
29
30 def has_output(self):
31 return self.server_name is not None
32
6a6986bc 33FilterSpec.filter_specs.insert(0, (lambda f: f.name == 'listsets', ListSetFilterSpec))
34
23b5b3d5 35# Ces deux classes permettent d'implémenter la possibilité d'avoir un champs readonly_fields
36# dans l.administration.
37# Ce champs est devenu natif à partir de la version 1.2
38# http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields
39from django import forms
40class ReadOnlyWidget(forms.Widget):
41 def __init__(self, original_value, display_value):
42 self.original_value = original_value
43 self.display_value = display_value
44
45 super(ReadOnlyWidget, self).__init__()
46
47 def render(self, name, value, attrs=None):
48 if self.display_value is not None:
49 output = self.display_value
50 else:
51 output = unicode(self.original_value)
52
d972b61d 53 # pour les relations
54 try:
55 output = ", ".join([ls.name for ls in self.original_value.get_query_set()])
56 except:
57 pass
58
23b5b3d5 59 is_url = re.match('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', output)
60 if is_url:
61 output = "<a target='_blank' href='%s'>%s</a>" % (output, output)
d972b61d 62
23b5b3d5 63 return mark_safe(output)
64
65 def value_from_datadict(self, data, files, name):
66 return self.original_value
67
68class ReadOnlyAdminFields(object):
69 def get_form(self, request, obj=None):
70 form = super(ReadOnlyAdminFields, self).get_form(request, obj)
71
72 if hasattr(self, 'readonly_fields'):
73 for field_name in self.readonly_fields:
74 if field_name in form.base_fields:
75
76 if hasattr(obj, 'get_%s_display' % field_name):
77 display_value = getattr(obj, 'get_%s_display' % field_name)()
78 else:
79 display_value = None
80
81 form.base_fields[field_name].widget = ReadOnlyWidget(getattr(obj, field_name, ''), display_value)
82 form.base_fields[field_name].required = False
83 return form
84
85
86class RecordAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
a5f76eb4
EMS
87 fields = ['server', 'title', 'creator', 'description', 'modified',
88 'identifier', 'uri', 'source', 'contributor', 'publisher',
89 'type', 'format', 'language', 'disciplines', 'thematiques',
90 'pays', 'regions', 'validated']
23b5b3d5 91
92 search_fields = []
93 readonly_fields = []
da9020f3 94
a5f76eb4
EMS
95 list_filter = ('validated', 'server', 'listsets', 'pays', 'regions',
96 'disciplines', 'thematiques')
18dbd2cf
EMS
97 list_display = ('title', 'subject', 'uri_display', 'creator',
98 'est_complet', 'validated',)
99 list_editable = ('validated',)
100 list_per_page = 25
101
102 actions = ['assigner_pays', 'assigner_regions', 'assigner_disciplines',
e3c3296e 103 'assigner_thematiques']
da9020f3 104
23b5b3d5 105 def __init__(self, *args, **kwargs):
106 """Surcharge l'initialisation pour définir les champs de recherche dynamiquement,
107 et les champs en lecture seule uniquement."""
108 self.search_fields = META.keys()
109 self.readonly_fields = META.keys()
d972b61d 110 self.readonly_fields.append('listsets')
23b5b3d5 111 super(RecordAdmin, self).__init__(*args, **kwargs)
6d885e0c 112
18dbd2cf
EMS
113 # Fonctions pour présenter l'information
114
6d885e0c 115 def est_complet(self, obj):
116 """ """
117 v = obj.est_complet()
118 return '<img src="/admin_media/img/admin/icon-%s.gif" alt="%d"/>' % (('no','yes')[v], v)
119 est_complet.allow_tags = True
18dbd2cf 120 est_complet.short_description = u'complet'
23b5b3d5 121
18dbd2cf 122 def uri_display(self, obj):
da9020f3 123 """ """
124 return "<a target='_blank' href='%s'>%s</a>" % (obj.uri, obj.uri)
18dbd2cf
EMS
125 uri_display.allow_tags = True
126 uri_display.short_description = u'lien'
da9020f3 127
18dbd2cf 128 def description_display(self, obj):
da9020f3 129 """ """
23b5b3d5 130 max = 140
131 if obj.description is not None and len(obj.description) > max:
132 return "%s..." % obj.description[:max]
133 else:
134 return obj.description
18dbd2cf 135 description_display.short_description = u'description'
da9020f3 136
18dbd2cf 137 # Actions
2be148fe 138
e3c3296e 139 def assigner_pays(self, request, queryset):
140 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
141 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('pays', ",".join(selected)))
18dbd2cf 142 assigner_pays.short_description = u'Assigner des pays'
e3c3296e 143
144 def assigner_regions(self, request, queryset):
145 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
264a3210
EMS
146 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='record')) + '?ids=' + ','.join(selected))
147 assigner_regions.short_description = u'Assigner des régions'
e3c3296e 148
149 def assigner_thematiques(self, request, queryset):
150 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
151 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('thematiques', ",".join(selected)))
18dbd2cf 152 assigner_thematiques.short_description = u'Assigner des thématiques'
e3c3296e 153
154 def assigner_disciplines(self, request, queryset):
155 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
264a3210
EMS
156 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='record')) + '?ids=' + ','.join(selected))
157 assigner_disciplines.short_description = u'Assigner des disciplines'
e3c3296e 158
da9020f3 159admin.site.register(Record, RecordAdmin)
160
d972b61d 161class ListSetAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
9eda5d6c 162 fields = ['spec', 'name', 'server', 'validated' ]
d972b61d 163 list_display = fields
164 readonly_fields = ['spec', 'name', 'server',]
165 list_filter = ('server',)
166
167admin.site.register(ListSet, ListSetAdmin)
168
23b5b3d5 169class HarvestLogAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
a85ba76e 170 fields = ['context', 'name', 'added', 'updated', 'processed', 'record']
23b5b3d5 171 list_display = fields + ['date']
172 admin_order_fields = ['date']
173 search_fields = fields
174 readonly_fields = fields
175 list_filter = ('context',)
176
177admin.site.register(HarvestLog, HarvestLogAdmin)
6d885e0c 178
179class ProfileInline(admin.TabularInline):
180 model = Profile
181 fk_name = 'user'
182 max_num = 1
183
184class UserProfileAdmin(UserAdmin):
185 inlines = [ProfileInline, ]
186
187admin.site.unregister(User)
188admin.site.register(User, UserProfileAdmin)
189
f554ef70 190class ActualiteAdmin(admin.ModelAdmin):
a5f76eb4 191 list_filter = ('visible', 'disciplines', 'regions')
ccbc4363 192 list_display = ('titre', 'source', 'date', 'visible')
264a3210 193 actions = ['rendre_visible', 'rendre_invisible', 'assigner_regions', 'assigner_disciplines']
f554ef70 194
195 # actions
196 def rendre_visible(self, request, queryset):
197 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
198 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('actualite', 'visible', ",".join(selected)))
199
200 def rendre_invisible(self, request, queryset):
201 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
202 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('actualite', 'invisible', ",".join(selected)))
203
264a3210
EMS
204 def assigner_regions(self, request, queryset):
205 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
206 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='actualite')) + '?ids=' + ','.join(selected))
207 assigner_regions.short_description = u'Assigner des régions'
208
209 def assigner_disciplines(self, request, queryset):
210 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
211 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='actualite')) + '?ids=' + ','.join(selected))
212 assigner_disciplines.short_description = u'Assigner des disciplines'
213
f554ef70 214admin.site.register(Actualite, ActualiteAdmin)
b7a741ad 215
216
73309469 217class EvenementAdminForm(forms.ModelForm):
218 class Meta:
219 model = Evenement
220
221 def clean(self,):
222 cleaned_data = self.cleaned_data
223 debut = cleaned_data.get("debut")
224 fin = cleaned_data.get("fin")
225 if debut > fin:
226 raise forms.ValidationError("La date de fin ne doit pas être antérieure à la date de début")
227 return cleaned_data
228
b7a741ad 229class EvenementAdmin(admin.ModelAdmin):
73309469 230 form = EvenementAdminForm
a5f76eb4 231 list_filter = ('approuve', 'regions', 'discipline', 'discipline_secondaire')
b7a741ad 232 list_display = ('titre', 'debut', 'fin', 'lieu', 'approuve')
264a3210
EMS
233 fields = ['titre', 'discipline', 'discipline_secondaire', 'mots_cles',
234 'type', 'fuseau', 'debut', 'fin', 'lieu', 'regions',
235 'description', 'contact', 'url', 'approuve']
236 actions = ['assigner_regions', 'assigner_disciplines']
237
238 def assigner_regions(self, request, queryset):
239 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
240 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='evenement')) + '?ids=' + ','.join(selected))
241 assigner_regions.short_description = u'Assigner des régions'
242
243 def assigner_disciplines(self, request, queryset):
244 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
245 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='evenement')) + '?ids=' + ','.join(selected))
246 assigner_disciplines.short_description = u'Assigner des disciplines'
b7a741ad 247
248admin.site.register(Evenement, EvenementAdmin)
249
250
251