Added/corrected docstrings for custom model fields and EntityProxyFields (now renamed...
[philo.git] / philo / contrib / sobol / admin.py
1 from functools import update_wrapper
2
3 from django.conf import settings
4 from django.conf.urls.defaults import patterns, url
5 from django.contrib import admin
6 from django.core.urlresolvers import reverse
7 from django.db.models import Count
8 from django.http import HttpResponseRedirect, Http404
9 from django.shortcuts import render_to_response
10 from django.template import RequestContext
11 from django.utils.translation import ugettext_lazy as _
12
13 from philo.admin import EntityAdmin
14 from philo.contrib.sobol.models import Search, ResultURL, SearchView
15
16
17 class ResultURLInline(admin.TabularInline):
18         model = ResultURL
19         readonly_fields = ('url',)
20         can_delete = False
21         extra = 0
22         max_num = 0
23
24
25 class SearchAdmin(admin.ModelAdmin):
26         readonly_fields = ('string',)
27         inlines = [ResultURLInline]
28         list_display = ['string', 'unique_urls', 'total_clicks']
29         search_fields = ['string', 'result_urls__url']
30         actions = ['results_action']
31         if 'grappelli' in settings.INSTALLED_APPS:
32                 results_template = 'admin/sobol/search/grappelli_results.html'
33         else:
34                 results_template = 'admin/sobol/search/results.html'
35         
36         def get_urls(self):
37                 urlpatterns = super(SearchAdmin, self).get_urls()
38                 
39                 def wrap(view):
40                         def wrapper(*args, **kwargs):
41                                 return self.admin_site.admin_view(view)(*args, **kwargs)
42                         return update_wrapper(wrapper, view)
43                 
44                 info = self.model._meta.app_label, self.model._meta.module_name
45                 
46                 urlpatterns = patterns('',
47                         url(r'^results/$', wrap(self.results_view), name="%s_%s_selected_results" % info),
48                         url(r'^(.+)/results/$', wrap(self.results_view), name="%s_%s_results" % info)
49                 ) + urlpatterns
50                 return urlpatterns
51         
52         def unique_urls(self, obj):
53                 return obj.unique_urls
54         unique_urls.admin_order_field = 'unique_urls'
55         
56         def total_clicks(self, obj):
57                 return obj.total_clicks
58         total_clicks.admin_order_field = 'total_clicks'
59         
60         def queryset(self, request):
61                 qs = super(SearchAdmin, self).queryset(request)
62                 return qs.annotate(total_clicks=Count('result_urls__clicks', distinct=True), unique_urls=Count('result_urls', distinct=True))
63         
64         def results_action(self, request, queryset):
65                 info = self.model._meta.app_label, self.model._meta.module_name
66                 if len(queryset) == 1:
67                         return HttpResponseRedirect(reverse("admin:%s_%s_results" % info, args=(queryset[0].pk,)))
68                 else:
69                         url = reverse("admin:%s_%s_selected_results" % info)
70                         return HttpResponseRedirect("%s?ids=%s" % (url, ','.join([str(item.pk) for item in queryset])))
71         results_action.short_description = "View results for selected %(verbose_name_plural)s"
72         
73         def results_view(self, request, object_id=None, extra_context=None):
74                 if object_id is not None:
75                         object_ids = [object_id]
76                 else:
77                         object_ids = request.GET.get('ids').split(',')
78                         
79                         if object_ids is None:
80                                 raise Http404
81                 
82                 qs = self.queryset(request).filter(pk__in=object_ids)
83                 opts = self.model._meta
84                 
85                 if len(object_ids) == 1:
86                         title = _(u"Search results for %s" % qs[0])
87                 else:
88                         title = _(u"Search results for multiple objects")
89                 
90                 context = {
91                         'title': title,
92                         'queryset': qs,
93                         'opts': opts,
94                         'root_path': self.admin_site.root_path,
95                         'app_label': opts.app_label
96                 }
97                 return render_to_response(self.results_template, context, context_instance=RequestContext(request))
98
99
100 class SearchViewAdmin(EntityAdmin):
101         raw_id_fields = ('results_page',)
102         related_lookup_fields = {'fk': raw_id_fields}
103
104
105 admin.site.register(Search, SearchAdmin)
106 admin.site.register(SearchView, SearchViewAdmin)