[#3416] Ressources (edition) Permet d'éditer les champs
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / admin.py
CommitLineData
6ef8ead4 1# -*- encoding: utf-8 -*-
29e2a8fd 2import operator
116db1fd 3
da048859 4from auf.django.references import models as ref
31249cf3 5from django import forms
264a3210 6from django.core.urlresolvers import reverse as url
6ef8ead4 7from django.contrib import admin
6d885e0c 8from django.contrib.auth.admin import UserAdmin
9from django.contrib.auth.models import User
da048859
EMS
10from django.db.models import Q
11from django.db.models.query import QuerySet
e3c3296e 12from django.http import HttpResponseRedirect
116db1fd 13
da048859
EMS
14from auf_savoirs_en_partage.savoirs.globals import META
15from auf_savoirs_en_partage.savoirs.models import \
31249cf3
EMS
16 SourceActualite, Actualite, ActualiteVoir, \
17 Evenement, EvenementVoir, Record, RecordEdit, \
18 RecordCategorie, ListSet, HarvestLog, Profile, PageStatique
81fe476e 19
31249cf3
EMS
20
21class ListSetListFilter(admin.RelatedFieldListFilter):
6a6986bc 22 """
31249cf3
EMS
23 Filtre custom automatiquement lié à un field nommé 'listsets'. Il a pour
24 but de s'afficher lorsqu'un server a déjà été présélectionné. Dans ce
25 cas, il affiche une liste qui contient les listsets de ce server.
6a6986bc 26 """
31249cf3
EMS
27 def __init__(self, field, request, params, model, model_admin, field_path):
28 super(ListSetListFilter, self).__init__(
29 field, request, params, model, model_admin, field_path
30 )
6a6986bc 31 self.server_name = request.GET.get('server', None)
32
33 def has_output(self):
34 return self.server_name is not None
35
23b5b3d5 36
da048859
EMS
37class AllRegionsListFilter(admin.SimpleListFilter):
38 """
39 Filtre qui offre aussi les régions inactives dans ses choix.
40 """
41 title = u'région'
42 parameter_name = 'regions'
43
44 def lookups(self, request, model_admin):
45 return [(r.id, r.nom) for r in ref.Region.avec_inactifs.all()]
46
47 def queryset(self, request, queryset):
48 return queryset.filter(regions=self.value())
49
50
5212238e
EMS
51class RecordAdminQuerySet(QuerySet):
52
53 def filter(self, *args, **kwargs):
54 """Gère des filtres supplémentaires pour l'admin.
31249cf3 55
5212238e
EMS
56 C'est la seule façon que j'ai trouvée de contourner les mécanismes
57 de recherche de l'admin."""
58 search = kwargs.pop('admin_search', None)
59 search_titre = kwargs.pop('admin_search_titre', None)
60 search_sujet = kwargs.pop('admin_search_sujet', None)
61 search_description = kwargs.pop('admin_search_description', None)
62 search_auteur = kwargs.pop('admin_search_auteur', None)
63
64 if search:
65 qs = self
31249cf3
EMS
66 search_all = not (search_titre or search_description or
67 search_sujet or search_auteur)
5212238e
EMS
68 fields = []
69 if search_titre or search_all:
70 fields += ['title', 'alt_title']
71 if search_description or search_all:
72 fields += ['description', 'abstract']
73 if search_sujet or search_all:
74 fields += ['subject']
75 if search_auteur or search_all:
76 fields += ['creator', 'contributor']
77
78 for bit in search.split():
31249cf3
EMS
79 or_queries = [Q(**{field + '__icontains': bit})
80 for field in fields]
5212238e
EMS
81 qs = qs.filter(reduce(operator.or_, or_queries))
82
83 if args or kwargs:
84 qs = super(RecordAdminQuerySet, qs).filter(*args, **kwargs)
85 return qs
86 else:
87 return super(RecordAdminQuerySet, self).filter(*args, **kwargs)
23b5b3d5 88
31249cf3
EMS
89
90class RecordAdmin(admin.ModelAdmin):
91 fields = ('server', 'title', 'creator', 'description', 'modified',
a5f76eb4 92 'identifier', 'uri', 'source', 'contributor', 'publisher',
656b9c0f 93 'type', 'format', 'language', 'categorie', 'disciplines',
31249cf3
EMS
94 'thematiques', 'pays', 'regions', 'validated')
95
96 list_filter = (
97 'validated', 'server', ('listsets', ListSetListFilter), 'pays',
da048859 98 AllRegionsListFilter, 'disciplines', 'thematiques', 'categorie'
31249cf3
EMS
99 )
100 list_display = (
101 'title', 'subject', 'uri_display', 'creator', 'categorie',
102 'est_complet', 'validated'
103 )
18dbd2cf
EMS
104 list_editable = ('validated',)
105 list_per_page = 25
106
31249cf3
EMS
107 actions = ('assigner_pays', 'assigner_regions', 'assigner_disciplines',
108 'assigner_thematiques', 'assigner_categorie')
da9020f3 109
23b5b3d5 110 def __init__(self, *args, **kwargs):
31249cf3
EMS
111 """
112 Surcharge l'initialisation pour définir les champs de recherche
113 dynamiquement, et les champs en lecture seule uniquement.
114 """
23b5b3d5 115 self.readonly_fields = META.keys()
d972b61d 116 self.readonly_fields.append('listsets')
31249cf3 117 super(RecordAdmin, self).__init__(*args, **kwargs)
6d885e0c 118
1719bf4e 119 def queryset(self, request):
5212238e 120 return RecordAdminQuerySet(Record)
77b0fac0
EMS
121
122 # Présentation de l'information
31249cf3 123
6d885e0c 124 def est_complet(self, obj):
6d885e0c 125 v = obj.est_complet()
89f07b48 126 return '<img src="/static/admin/img/icon-%s.gif" alt="%d"/>' % (
31249cf3
EMS
127 ('no', 'yes')[v], v
128 )
6d885e0c 129 est_complet.allow_tags = True
18dbd2cf 130 est_complet.short_description = u'complet'
31249cf3 131
18dbd2cf 132 def uri_display(self, obj):
da9020f3 133 return "<a target='_blank' href='%s'>%s</a>" % (obj.uri, obj.uri)
18dbd2cf
EMS
134 uri_display.allow_tags = True
135 uri_display.short_description = u'lien'
da9020f3 136
18dbd2cf 137 def description_display(self, obj):
23b5b3d5 138 max = 140
31249cf3 139 if obj.description is not None and len(obj.description) > max:
23b5b3d5 140 return "%s..." % obj.description[:max]
141 else:
142 return obj.description
18dbd2cf 143 description_display.short_description = u'description'
da9020f3 144
18dbd2cf 145 # Actions
2be148fe 146
e3c3296e 147 def assigner_pays(self, request, queryset):
b07400fb
PP
148 selected = queryset.values_list('id', flat=True)
149 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
150 return HttpResponseRedirect(
151 "/admin/assigner_%s?ids=%s" % ('pays', selected)
152 )
18dbd2cf 153 assigner_pays.short_description = u'Assigner des pays'
e3c3296e 154
155 def assigner_regions(self, request, queryset):
b07400fb
PP
156 selected = queryset.values_list('id', flat=True)
157 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
158 return HttpResponseRedirect(url(
159 'assigner_regions',
160 kwargs={'app_name': 'savoirs', 'model_name': 'record'}
161 ) + '?ids=' + selected)
264a3210 162 assigner_regions.short_description = u'Assigner des régions'
e3c3296e 163
164 def assigner_thematiques(self, request, queryset):
b07400fb
PP
165 selected = queryset.values_list('id', flat=True)
166 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
167 return HttpResponseRedirect(
168 "/admin/assigner_%s?ids=%s" % ('thematiques', selected)
169 )
18dbd2cf 170 assigner_thematiques.short_description = u'Assigner des thématiques'
e3c3296e 171
172 def assigner_disciplines(self, request, queryset):
b07400fb
PP
173 selected = queryset.values_list('id', flat=True)
174 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
175 return HttpResponseRedirect(url(
176 'assigner_disciplines',
177 kwargs={'app_name': 'savoirs', 'model_name': 'record'}
178 ) + '?ids=' + selected)
264a3210 179 assigner_disciplines.short_description = u'Assigner des disciplines'
116db1fd 180
656b9c0f 181 def assigner_categorie(self, request, queryset):
b07400fb
PP
182 selected = queryset.values_list('id', flat=True)
183 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
184 return HttpResponseRedirect(
185 "/admin/assigner_%s?ids=%s" % ('categorie', selected)
186 )
656b9c0f
PP
187 assigner_categorie.short_description = u'Assigner une catégorie'
188
da9020f3 189admin.site.register(Record, RecordAdmin)
190
927764f9 191
31249cf3
EMS
192class RecordEditAdmin(RecordAdmin):
193 list_editable = ()
4bf80bb5 194 change_list_template = "admin/savoirs/record/change_list.html"
927764f9
PP
195
196 def __init__(self, model, admin_site):
197 super(RecordEditAdmin, self).__init__(model, admin_site)
16176279 198 self.readonly_fields = ()
927764f9
PP
199
200 def get_actions(self, request):
201 actions = super(RecordEditAdmin, self).get_actions(request)
927764f9 202 del actions['assigner_pays']
16176279
PP
203 del actions['assigner_regions']
204 del actions['assigner_disciplines']
927764f9 205 del actions['assigner_thematiques']
31249cf3 206 del actions['assigner_categorie']
927764f9
PP
207
208 return actions
209
927764f9
PP
210admin.site.register(RecordEdit, RecordEditAdmin)
211
212
31249cf3
EMS
213class ListSetAdmin(admin.ModelAdmin):
214 fields = ('spec', 'name', 'server', 'validated')
d972b61d 215 list_display = fields
31249cf3 216 readonly_fields = ('spec', 'name', 'server')
d972b61d 217 list_filter = ('server',)
218
219admin.site.register(ListSet, ListSetAdmin)
220
31249cf3
EMS
221
222class HarvestLogAdmin(admin.ModelAdmin):
223 fields = ('context', 'name', 'added', 'updated', 'processed', 'record')
224 list_display = fields + ('date',)
225 admin_order_fields = ('date',)
226 search_fields = (
227 'context', 'name', 'added', 'updated', 'processed', 'record__title'
228 )
23b5b3d5 229 readonly_fields = fields
230 list_filter = ('context',)
231
232admin.site.register(HarvestLog, HarvestLogAdmin)
6d885e0c 233
31249cf3 234
6d885e0c 235class ProfileInline(admin.TabularInline):
236 model = Profile
237 fk_name = 'user'
238 max_num = 1
239
31249cf3 240
6d885e0c 241class UserProfileAdmin(UserAdmin):
31249cf3 242 inlines = (ProfileInline,)
6d885e0c 243
244admin.site.unregister(User)
245admin.site.register(User, UserProfileAdmin)
246
31249cf3 247
f554ef70 248class ActualiteAdmin(admin.ModelAdmin):
da048859 249 list_filter = ('visible', 'disciplines', AllRegionsListFilter)
ccbc4363 250 list_display = ('titre', 'source', 'date', 'visible')
31249cf3 251 list_editable = ('visible',)
befea523 252 search_fields = ('titre', 'texte')
31249cf3
EMS
253 actions = (
254 'rendre_visible', 'rendre_invisible', 'assigner_regions',
255 'assigner_disciplines'
256 )
f554ef70 257
1719bf4e 258 def queryset(self, request):
29e2a8fd 259 return Actualite.all_objects.get_query_set()
1719bf4e 260
f554ef70 261 # actions
262 def rendre_visible(self, request, queryset):
b07400fb
PP
263 selected = queryset.values_list('id', flat=True)
264 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
265 return HttpResponseRedirect(
266 "/admin/confirmation/%s/%s?ids=%s" %
267 ('actualite', 'visible', selected)
268 )
f554ef70 269
270 def rendre_invisible(self, request, queryset):
b07400fb
PP
271 selected = queryset.values_list('id', flat=True)
272 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
273 return HttpResponseRedirect(
274 "/admin/confirmation/%s/%s?ids=%s" %
275 ('actualite', 'invisible', selected)
276 )
f554ef70 277
264a3210 278 def assigner_regions(self, request, queryset):
b07400fb
PP
279 selected = queryset.values_list('id', flat=True)
280 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
281 return HttpResponseRedirect(url(
282 'assigner_regions',
283 kwargs={'app_name': 'savoirs', 'model_name': 'actualite'}
284 ) + '?ids=' + selected)
264a3210
EMS
285 assigner_regions.short_description = u'Assigner des régions'
286
287 def assigner_disciplines(self, request, queryset):
b07400fb
PP
288 selected = queryset.values_list('id', flat=True)
289 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
290 return HttpResponseRedirect(url(
291 'assigner_disciplines',
292 kwargs={'app_name': 'savoirs', 'model_name': 'actualite'}
293 ) + '?ids=' + selected)
264a3210
EMS
294 assigner_disciplines.short_description = u'Assigner des disciplines'
295
f554ef70 296admin.site.register(Actualite, ActualiteAdmin)
b7a741ad 297
31249cf3 298
81fe476e
PP
299class ActualiteVoirAdmin(ActualiteAdmin):
300
301 actions = None
31249cf3
EMS
302 list_editable = ()
303 fields = (
304 'titre', 'texte', 'url', 'date', 'visible', 'ancienid', 'source',
305 'disciplines', 'regions'
306 )
81fe476e
PP
307
308 def __init__(self, model, admin_site):
309 super(ActualiteVoirAdmin, self).__init__(model, admin_site)
81fe476e
PP
310 self.readonly_fields = self.fields
311
312
313admin.site.register(ActualiteVoir, ActualiteVoirAdmin)
314
31249cf3 315
db2999fa 316class SourceActualiteAdmin(admin.ModelAdmin):
31249cf3
EMS
317 actions = ('update_sources',)
318 list_display = ('nom', 'url', 'type')
319 list_filter = ('type',)
db2999fa
EMS
320
321 def update_sources(self, request, queryset):
322 for source in queryset:
323 source.update()
324 update_sources.short_description = u'Mettre à jour les fils sélectionnés'
325
326admin.site.register(SourceActualite, SourceActualiteAdmin)
b7a741ad 327
31249cf3 328
73309469 329class EvenementAdminForm(forms.ModelForm):
86983865 330 mots_cles = forms.CharField(label='Mots-clés', required=False)
86983865 331
73309469 332 class Meta:
333 model = Evenement
334
335 def clean(self,):
336 cleaned_data = self.cleaned_data
337 debut = cleaned_data.get("debut")
338 fin = cleaned_data.get("fin")
7495bc13 339 if debut and fin and debut > fin:
31249cf3
EMS
340 raise forms.ValidationError(
341 "La date de fin ne doit pas être antérieure à la date de début"
342 )
73309469 343 return cleaned_data
344
31249cf3 345
b7a741ad 346class EvenementAdmin(admin.ModelAdmin):
73309469 347 form = EvenementAdminForm
31249cf3 348 list_filter = (
da048859 349 'approuve', AllRegionsListFilter, 'discipline', 'discipline_secondaire'
31249cf3 350 )
731ef7ab 351 list_display = ('titre', 'debut', 'fin', 'ville', 'pays', 'approuve')
31249cf3
EMS
352 fields = ('titre', 'discipline', 'discipline_secondaire', 'mots_cles',
353 'type', 'adresse', 'ville', 'pays', 'fuseau', 'debut', 'fin',
354 'piece_jointe', 'regions', 'description', 'prenom', 'nom',
355 'courriel', 'url', 'approuve')
befea523 356 search_fields = ('titre', 'description')
31249cf3 357 actions = ('assigner_regions', 'assigner_disciplines')
264a3210 358
1719bf4e 359 def queryset(self, request):
29e2a8fd 360 return Evenement.all_objects.get_query_set()
1719bf4e 361
264a3210 362 def assigner_regions(self, request, queryset):
b07400fb
PP
363 selected = queryset.values_list('id', flat=True)
364 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
365 return HttpResponseRedirect(url(
366 'assigner_regions',
367 kwargs={'app_name': 'savoirs', 'model_name': 'evenement'}
368 ) + '?ids=' + selected)
264a3210
EMS
369 assigner_regions.short_description = u'Assigner des régions'
370
371 def assigner_disciplines(self, request, queryset):
b07400fb
PP
372 selected = queryset.values_list('id', flat=True)
373 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
374 return HttpResponseRedirect(url(
375 'assigner_disciplines',
376 kwargs={'app_name': 'savoirs', 'model_name': 'evenement'}
377 ) + '?ids=' + selected)
264a3210 378 assigner_disciplines.short_description = u'Assigner des disciplines'
b7a741ad 379
380admin.site.register(Evenement, EvenementAdmin)
381
31249cf3 382
81fe476e
PP
383class EvenementVoirAdmin(EvenementAdmin):
384
385 actions = None
31249cf3 386 list_editable = ()
81fe476e
PP
387
388 def __init__(self, model, admin_site):
389 super(EvenementVoirAdmin, self).__init__(model, admin_site)
81fe476e
PP
390 self.readonly_fields = self.fields
391
81fe476e
PP
392admin.site.register(EvenementVoir, EvenementVoirAdmin)
393
31249cf3 394
f09bc1c6 395class PageStatiqueAdmin(admin.ModelAdmin):
31249cf3
EMS
396 list_display = ('titre', 'id')
397 list_display_links = ('titre', 'id')
b7a741ad 398
f09bc1c6 399 class Media:
31249cf3 400 js = ('js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js')
f09bc1c6
EMS
401
402admin.site.register(PageStatique, PageStatiqueAdmin)
b7a741ad 403
656b9c0f
PP
404
405admin.site.register(RecordCategorie)