Assigner les disciplines et régions en bloc dans l'admin
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / admin.py
1 # -*- encoding: utf-8 -*-
2 import re
3
4 from django.core.urlresolvers import reverse as url
5 from django.db import models
6 from django.contrib import admin
7 from django.contrib.auth.admin import UserAdmin
8 from django.contrib.auth.models import User
9 from django.contrib.admin.filterspecs import RelatedFilterSpec, FilterSpec
10 from django.utils.safestring import mark_safe
11 from django.utils.translation import ugettext as _
12 from django.utils.encoding import smart_unicode, iri_to_uri
13 from django.http import HttpResponseRedirect
14
15 from models import SourceActualite, Actualite, Discipline, Evenement, Record, ListSet, HarvestLog, Profile
16 from savoirs.globals import META
17
18 admin.site.register(SourceActualite)
19
20 class 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
33 FilterSpec.filter_specs.insert(0, (lambda f: f.name == 'listsets', ListSetFilterSpec))
34
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
39 from django import forms
40 class 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
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
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)
62
63 return mark_safe(output)
64
65 def value_from_datadict(self, data, files, name):
66 return self.original_value
67
68 class 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
86 class RecordAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
87 fields = [
88 'server',
89 'title',
90 'creator',
91 'description',
92 'modified',
93 'identifier',
94 'uri',
95 'source',
96 'contributor',
97 'publisher',
98 'type',
99 'format',
100 'language',
101 'disciplines',
102 'thematiques',
103 'pays',
104 'regions',
105 'validated',
106 ]
107
108 search_fields = []
109 readonly_fields = []
110
111 list_filter = (
112 'validated',
113 'server',
114 'listsets',
115 'pays',
116 'regions',
117 'disciplines',
118 'thematiques',
119 )
120 list_display = (
121 #OAI et extra AUF
122 'title',
123 'subject',
124 '_description',
125 '_uri',
126 #'server',
127 'identifier',
128 #'source',
129 'modified',
130 'creator',
131 #'contributor',
132 #'language',
133 #'publisher',
134 'format',
135 'type',
136
137 #SEP 2 (aucune données récoltées)
138 #'alt_title',
139 #'abstract',
140 #'creation',
141 #'issued',
142 #'isbn',
143 #'orig_lang',
144 'est_complet',
145 'validated',
146 )
147 actions = ['valider_references',
148 'invalider_references',
149 'assigner_pays',
150 'assigner_regions',
151 'assigner_disciplines',
152 'assigner_thematiques']
153
154 # fonctions pour présenter l'information
155 def __init__(self, *args, **kwargs):
156 """Surcharge l'initialisation pour définir les champs de recherche dynamiquement,
157 et les champs en lecture seule uniquement."""
158 self.search_fields = META.keys()
159 self.readonly_fields = META.keys()
160 self.readonly_fields.append('listsets')
161 super(RecordAdmin, self).__init__(*args, **kwargs)
162
163 def est_complet(self, obj):
164 """ """
165 v = obj.est_complet()
166 return '<img src="/admin_media/img/admin/icon-%s.gif" alt="%d"/>' % (('no','yes')[v], v)
167 est_complet.allow_tags = True
168
169 def _uri(self, obj):
170 """ """
171 return "<a target='_blank' href='%s'>%s</a>" % (obj.uri, obj.uri)
172 _uri.allow_tags = True
173
174 def _description(self, obj):
175 """ """
176 max = 140
177 if obj.description is not None and len(obj.description) > max:
178 return "%s..." % obj.description[:max]
179 else:
180 return obj.description
181
182 # actions
183 def valider_references(self, request, queryset):
184 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
185 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('record', 'valider', ",".join(selected)))
186
187 def invalider_references(self, request, queryset):
188 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
189 return HttpResponseRedirect("/admin/confirmation/%s/%s/?ids=%s" % ('record', 'invalider', ",".join(selected)))
190
191 def assigner_pays(self, request, queryset):
192 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
193 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('pays', ",".join(selected)))
194
195 def assigner_regions(self, request, queryset):
196 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
197 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='record')) + '?ids=' + ','.join(selected))
198 assigner_regions.short_description = u'Assigner des régions'
199
200 def assigner_thematiques(self, request, queryset):
201 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
202 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('thematiques', ",".join(selected)))
203
204 def assigner_disciplines(self, request, queryset):
205 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
206 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='record')) + '?ids=' + ','.join(selected))
207 assigner_disciplines.short_description = u'Assigner des disciplines'
208
209 admin.site.register(Record, RecordAdmin)
210
211 class ListSetAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
212 fields = ['spec', 'name', 'server', 'validated' ]
213 list_display = fields
214 readonly_fields = ['spec', 'name', 'server',]
215 list_filter = ('server',)
216
217 admin.site.register(ListSet, ListSetAdmin)
218
219 class HarvestLogAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
220 fields = ['context', 'name', 'added', 'updated', 'processed', 'record']
221 list_display = fields + ['date']
222 admin_order_fields = ['date']
223 search_fields = fields
224 readonly_fields = fields
225 list_filter = ('context',)
226
227 admin.site.register(HarvestLog, HarvestLogAdmin)
228
229 class ProfileInline(admin.TabularInline):
230 model = Profile
231 fk_name = 'user'
232 max_num = 1
233
234 class UserProfileAdmin(UserAdmin):
235 inlines = [ProfileInline, ]
236
237 admin.site.unregister(User)
238 admin.site.register(User, UserProfileAdmin)
239
240 class ActualiteAdmin(admin.ModelAdmin):
241 list_filter = ('visible',)
242 list_display = ('titre', 'source', 'date', 'visible')
243 actions = ['rendre_visible', 'rendre_invisible', 'assigner_regions', 'assigner_disciplines']
244
245 # actions
246 def rendre_visible(self, request, queryset):
247 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
248 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('actualite', 'visible', ",".join(selected)))
249
250 def rendre_invisible(self, request, queryset):
251 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
252 return HttpResponseRedirect("/admin/confirmation/%s/%s?ids=%s" % ('actualite', 'invisible', ",".join(selected)))
253
254 def assigner_regions(self, request, queryset):
255 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
256 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='actualite')) + '?ids=' + ','.join(selected))
257 assigner_regions.short_description = u'Assigner des régions'
258
259 def assigner_disciplines(self, request, queryset):
260 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
261 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='actualite')) + '?ids=' + ','.join(selected))
262 assigner_disciplines.short_description = u'Assigner des disciplines'
263
264 admin.site.register(Actualite, ActualiteAdmin)
265
266
267 class EvenementAdminForm(forms.ModelForm):
268 class Meta:
269 model = Evenement
270
271 def clean(self,):
272 cleaned_data = self.cleaned_data
273 debut = cleaned_data.get("debut")
274 fin = cleaned_data.get("fin")
275 if debut > fin:
276 raise forms.ValidationError("La date de fin ne doit pas être antérieure à la date de début")
277 return cleaned_data
278
279 class EvenementAdmin(admin.ModelAdmin):
280 form = EvenementAdminForm
281 list_filter = ('approuve',)
282 list_display = ('titre', 'debut', 'fin', 'lieu', 'approuve')
283 fields = ['titre', 'discipline', 'discipline_secondaire', 'mots_cles',
284 'type', 'fuseau', 'debut', 'fin', 'lieu', 'regions',
285 'description', 'contact', 'url', 'approuve']
286 actions = ['assigner_regions', 'assigner_disciplines']
287
288 def assigner_regions(self, request, queryset):
289 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
290 return HttpResponseRedirect(url('assigner_regions', kwargs=dict(app_name='savoirs', model_name='evenement')) + '?ids=' + ','.join(selected))
291 assigner_regions.short_description = u'Assigner des régions'
292
293 def assigner_disciplines(self, request, queryset):
294 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
295 return HttpResponseRedirect(url('assigner_disciplines', kwargs=dict(app_name='savoirs', model_name='evenement')) + '?ids=' + ','.join(selected))
296 assigner_disciplines.short_description = u'Assigner des disciplines'
297
298 admin.site.register(Evenement, EvenementAdmin)
299
300
301