Ajout de search fields
[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()
31249cf3
EMS
126 return '<img src="/admin_media/img/admin/icon-%s.gif" alt="%d"/>' % (
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)
927764f9
PP
198 self.readonly_fields = self.fields
199
200 def get_actions(self, request):
201 actions = super(RecordEditAdmin, self).get_actions(request)
927764f9
PP
202 del actions['assigner_pays']
203 del actions['assigner_thematiques']
31249cf3 204 del actions['assigner_categorie']
927764f9
PP
205
206 return actions
207
208 def assigner_disciplines(self, request, queryset):
209 selected = queryset.values_list('id', flat=True)
210 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
211 return HttpResponseRedirect(url(
212 'assigner_disciplines',
213 kwargs={'app_name': 'savoirs', 'model_name': 'recordedit'}
214 ) + '?ids=' + selected)
927764f9
PP
215 assigner_disciplines.short_description = u'Assigner des disciplines'
216
217 def assigner_regions(self, request, queryset):
218 selected = queryset.values_list('id', flat=True)
219 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
220 return HttpResponseRedirect(url(
221 'assigner_regions',
222 kwargs={'app_name': 'savoirs', 'model_name': 'recordedit'}
223 ) + '?ids=' + selected)
927764f9
PP
224 assigner_regions.short_description = u'Assigner des régions'
225
226admin.site.register(RecordEdit, RecordEditAdmin)
227
228
31249cf3
EMS
229class ListSetAdmin(admin.ModelAdmin):
230 fields = ('spec', 'name', 'server', 'validated')
d972b61d 231 list_display = fields
31249cf3 232 readonly_fields = ('spec', 'name', 'server')
d972b61d 233 list_filter = ('server',)
234
235admin.site.register(ListSet, ListSetAdmin)
236
31249cf3
EMS
237
238class HarvestLogAdmin(admin.ModelAdmin):
239 fields = ('context', 'name', 'added', 'updated', 'processed', 'record')
240 list_display = fields + ('date',)
241 admin_order_fields = ('date',)
242 search_fields = (
243 'context', 'name', 'added', 'updated', 'processed', 'record__title'
244 )
23b5b3d5 245 readonly_fields = fields
246 list_filter = ('context',)
247
248admin.site.register(HarvestLog, HarvestLogAdmin)
6d885e0c 249
31249cf3 250
6d885e0c 251class ProfileInline(admin.TabularInline):
252 model = Profile
253 fk_name = 'user'
254 max_num = 1
255
31249cf3 256
6d885e0c 257class UserProfileAdmin(UserAdmin):
31249cf3 258 inlines = (ProfileInline,)
6d885e0c 259
260admin.site.unregister(User)
261admin.site.register(User, UserProfileAdmin)
262
31249cf3 263
f554ef70 264class ActualiteAdmin(admin.ModelAdmin):
da048859 265 list_filter = ('visible', 'disciplines', AllRegionsListFilter)
ccbc4363 266 list_display = ('titre', 'source', 'date', 'visible')
31249cf3 267 list_editable = ('visible',)
befea523 268 search_fields = ('titre', 'texte')
31249cf3
EMS
269 actions = (
270 'rendre_visible', 'rendre_invisible', 'assigner_regions',
271 'assigner_disciplines'
272 )
f554ef70 273
1719bf4e 274 def queryset(self, request):
29e2a8fd 275 return Actualite.all_objects.get_query_set()
1719bf4e 276
f554ef70 277 # actions
278 def rendre_visible(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(
282 "/admin/confirmation/%s/%s?ids=%s" %
283 ('actualite', 'visible', selected)
284 )
f554ef70 285
286 def rendre_invisible(self, request, queryset):
b07400fb
PP
287 selected = queryset.values_list('id', flat=True)
288 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
289 return HttpResponseRedirect(
290 "/admin/confirmation/%s/%s?ids=%s" %
291 ('actualite', 'invisible', selected)
292 )
f554ef70 293
264a3210 294 def assigner_regions(self, request, queryset):
b07400fb
PP
295 selected = queryset.values_list('id', flat=True)
296 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
297 return HttpResponseRedirect(url(
298 'assigner_regions',
299 kwargs={'app_name': 'savoirs', 'model_name': 'actualite'}
300 ) + '?ids=' + selected)
264a3210
EMS
301 assigner_regions.short_description = u'Assigner des régions'
302
303 def assigner_disciplines(self, request, queryset):
b07400fb
PP
304 selected = queryset.values_list('id', flat=True)
305 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
306 return HttpResponseRedirect(url(
307 'assigner_disciplines',
308 kwargs={'app_name': 'savoirs', 'model_name': 'actualite'}
309 ) + '?ids=' + selected)
264a3210
EMS
310 assigner_disciplines.short_description = u'Assigner des disciplines'
311
f554ef70 312admin.site.register(Actualite, ActualiteAdmin)
b7a741ad 313
31249cf3 314
81fe476e
PP
315class ActualiteVoirAdmin(ActualiteAdmin):
316
317 actions = None
31249cf3
EMS
318 list_editable = ()
319 fields = (
320 'titre', 'texte', 'url', 'date', 'visible', 'ancienid', 'source',
321 'disciplines', 'regions'
322 )
81fe476e
PP
323
324 def __init__(self, model, admin_site):
325 super(ActualiteVoirAdmin, self).__init__(model, admin_site)
81fe476e
PP
326 self.readonly_fields = self.fields
327
328
329admin.site.register(ActualiteVoir, ActualiteVoirAdmin)
330
31249cf3 331
db2999fa 332class SourceActualiteAdmin(admin.ModelAdmin):
31249cf3
EMS
333 actions = ('update_sources',)
334 list_display = ('nom', 'url', 'type')
335 list_filter = ('type',)
db2999fa
EMS
336
337 def update_sources(self, request, queryset):
338 for source in queryset:
339 source.update()
340 update_sources.short_description = u'Mettre à jour les fils sélectionnés'
341
342admin.site.register(SourceActualite, SourceActualiteAdmin)
b7a741ad 343
31249cf3 344
73309469 345class EvenementAdminForm(forms.ModelForm):
86983865 346 mots_cles = forms.CharField(label='Mots-clés', required=False)
86983865 347
73309469 348 class Meta:
349 model = Evenement
350
351 def clean(self,):
352 cleaned_data = self.cleaned_data
353 debut = cleaned_data.get("debut")
354 fin = cleaned_data.get("fin")
7495bc13 355 if debut and fin and debut > fin:
31249cf3
EMS
356 raise forms.ValidationError(
357 "La date de fin ne doit pas être antérieure à la date de début"
358 )
73309469 359 return cleaned_data
360
31249cf3 361
b7a741ad 362class EvenementAdmin(admin.ModelAdmin):
73309469 363 form = EvenementAdminForm
31249cf3 364 list_filter = (
da048859 365 'approuve', AllRegionsListFilter, 'discipline', 'discipline_secondaire'
31249cf3 366 )
731ef7ab 367 list_display = ('titre', 'debut', 'fin', 'ville', 'pays', 'approuve')
31249cf3
EMS
368 fields = ('titre', 'discipline', 'discipline_secondaire', 'mots_cles',
369 'type', 'adresse', 'ville', 'pays', 'fuseau', 'debut', 'fin',
370 'piece_jointe', 'regions', 'description', 'prenom', 'nom',
371 'courriel', 'url', 'approuve')
befea523 372 search_fields = ('titre', 'description')
31249cf3 373 actions = ('assigner_regions', 'assigner_disciplines')
264a3210 374
1719bf4e 375 def queryset(self, request):
29e2a8fd 376 return Evenement.all_objects.get_query_set()
1719bf4e 377
264a3210 378 def assigner_regions(self, request, queryset):
b07400fb
PP
379 selected = queryset.values_list('id', flat=True)
380 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
381 return HttpResponseRedirect(url(
382 'assigner_regions',
383 kwargs={'app_name': 'savoirs', 'model_name': 'evenement'}
384 ) + '?ids=' + selected)
264a3210
EMS
385 assigner_regions.short_description = u'Assigner des régions'
386
387 def assigner_disciplines(self, request, queryset):
b07400fb
PP
388 selected = queryset.values_list('id', flat=True)
389 selected = ",".join("%s" % val for val in selected)
31249cf3
EMS
390 return HttpResponseRedirect(url(
391 'assigner_disciplines',
392 kwargs={'app_name': 'savoirs', 'model_name': 'evenement'}
393 ) + '?ids=' + selected)
264a3210 394 assigner_disciplines.short_description = u'Assigner des disciplines'
b7a741ad 395
396admin.site.register(Evenement, EvenementAdmin)
397
31249cf3 398
81fe476e
PP
399class EvenementVoirAdmin(EvenementAdmin):
400
401 actions = None
31249cf3 402 list_editable = ()
81fe476e
PP
403
404 def __init__(self, model, admin_site):
405 super(EvenementVoirAdmin, self).__init__(model, admin_site)
81fe476e
PP
406 self.readonly_fields = self.fields
407
81fe476e
PP
408admin.site.register(EvenementVoir, EvenementVoirAdmin)
409
31249cf3 410
f09bc1c6 411class PageStatiqueAdmin(admin.ModelAdmin):
31249cf3
EMS
412 list_display = ('titre', 'id')
413 list_display_links = ('titre', 'id')
b7a741ad 414
f09bc1c6 415 class Media:
31249cf3 416 js = ('js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js')
f09bc1c6
EMS
417
418admin.site.register(PageStatique, PageStatiqueAdmin)
b7a741ad 419
656b9c0f
PP
420
421admin.site.register(RecordCategorie)