|
1 from django import http |
|
2 from django.db import models |
|
3 from django.contrib.databrowse.datastructures import EasyModel |
|
4 from django.contrib.databrowse.sites import DatabrowsePlugin |
|
5 from django.shortcuts import render_to_response |
|
6 from django.utils.text import capfirst |
|
7 from django.utils.encoding import smart_str, force_unicode |
|
8 from django.utils.safestring import mark_safe |
|
9 from django.views.generic import date_based |
|
10 import urllib |
|
11 |
|
12 class FieldChoicePlugin(DatabrowsePlugin): |
|
13 def __init__(self, field_filter=None): |
|
14 # If field_filter is given, it should be a callable that takes a |
|
15 # Django database Field instance and returns True if that field should |
|
16 # be included. If field_filter is None, that all fields will be used. |
|
17 self.field_filter = field_filter |
|
18 |
|
19 def field_dict(self, model): |
|
20 """ |
|
21 Helper function that returns a dictionary of all fields in the given |
|
22 model. If self.field_filter is set, it only includes the fields that |
|
23 match the filter. |
|
24 """ |
|
25 if self.field_filter: |
|
26 return dict([(f.name, f) for f in model._meta.fields if self.field_filter(f)]) |
|
27 else: |
|
28 return dict([(f.name, f) for f in model._meta.fields if not f.rel and not f.primary_key and not f.unique and not isinstance(f, (models.AutoField, models.TextField))]) |
|
29 |
|
30 def model_index_html(self, request, model, site): |
|
31 fields = self.field_dict(model) |
|
32 if not fields: |
|
33 return u'' |
|
34 return mark_safe(u'<p class="filter"><strong>View by:</strong> %s</p>' % \ |
|
35 u', '.join(['<a href="fields/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()])) |
|
36 |
|
37 def urls(self, plugin_name, easy_instance_field): |
|
38 if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values(): |
|
39 field_value = smart_str(easy_instance_field.raw_value) |
|
40 return [mark_safe(u'%s%s/%s/%s/' % ( |
|
41 easy_instance_field.model.url(), |
|
42 plugin_name, easy_instance_field.field.name, |
|
43 urllib.quote(field_value, safe='')))] |
|
44 |
|
45 def model_view(self, request, model_databrowse, url): |
|
46 self.model, self.site = model_databrowse.model, model_databrowse.site |
|
47 self.fields = self.field_dict(self.model) |
|
48 |
|
49 # If the model has no fields with choices, there's no point in going |
|
50 # further. |
|
51 if not self.fields: |
|
52 raise http.Http404('The requested model has no fields.') |
|
53 |
|
54 if url is None: |
|
55 return self.homepage_view(request) |
|
56 url_bits = url.split('/', 1) |
|
57 if self.fields.has_key(url_bits[0]): |
|
58 return self.field_view(request, self.fields[url_bits[0]], *url_bits[1:]) |
|
59 |
|
60 raise http.Http404('The requested page does not exist.') |
|
61 |
|
62 def homepage_view(self, request): |
|
63 easy_model = EasyModel(self.site, self.model) |
|
64 field_list = self.fields.values() |
|
65 field_list.sort(lambda x, y: cmp(x.verbose_name, y.verbose_name)) |
|
66 return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list}) |
|
67 |
|
68 def field_view(self, request, field, value=None): |
|
69 easy_model = EasyModel(self.site, self.model) |
|
70 easy_field = easy_model.field(field.name) |
|
71 if value is not None: |
|
72 obj_list = easy_model.objects(**{field.name: value}) |
|
73 return render_to_response('databrowse/fieldchoice_detail.html', {'root_url': self.site.root_url, 'model': easy_model, 'field': easy_field, 'value': value, 'object_list': obj_list}) |
|
74 obj_list = [v[field.name] for v in self.model._default_manager.distinct().order_by(field.name).values(field.name)] |
|
75 return render_to_response('databrowse/fieldchoice_list.html', {'root_url': self.site.root_url, 'model': easy_model, 'field': easy_field, 'object_list': obj_list}) |