Implemented auto-escaping of variable output in templates. Fully controllable by...
[django.git] / django / contrib / databrowse / plugins / fieldchoices.py
blobdea6bac700db932c770534768658d6dde2c11024
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 datetime
11 import time
12 import urllib
14 class FieldChoicePlugin(DatabrowsePlugin):
15 def __init__(self, field_filter=None):
16 # If field_filter is given, it should be a callable that takes a
17 # Django database Field instance and returns True if that field should
18 # be included. If field_filter is None, that all fields will be used.
19 self.field_filter = field_filter
21 def field_dict(self, model):
22 """
23 Helper function that returns a dictionary of all fields in the given
24 model. If self.field_filter is set, it only includes the fields that
25 match the filter.
26 """
27 if self.field_filter:
28 return dict([(f.name, f) for f in model._meta.fields if self.field_filter(f)])
29 else:
30 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))])
32 def model_index_html(self, request, model, site):
33 fields = self.field_dict(model)
34 if not fields:
35 return u''
36 return mark_safe(u'<p class="filter"><strong>View by:</strong> %s</p>' % \
37 u', '.join(['<a href="fields/%s/">%s</a>' % (f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()]))
39 def urls(self, plugin_name, easy_instance_field):
40 if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
41 field_value = smart_str(easy_instance_field.raw_value)
42 return [mark_safe(u'%s%s/%s/%s/' % (
43 easy_instance_field.model.url(),
44 plugin_name, easy_instance_field.field.name,
45 urllib.quote(field_value, safe='')))]
47 def model_view(self, request, model_databrowse, url):
48 self.model, self.site = model_databrowse.model, model_databrowse.site
49 self.fields = self.field_dict(self.model)
51 # If the model has no fields with choices, there's no point in going
52 # further.
53 if not self.fields:
54 raise http.Http404('The requested model has no fields.')
56 if url is None:
57 return self.homepage_view(request)
58 url_bits = url.split('/', 1)
59 if self.fields.has_key(url_bits[0]):
60 return self.field_view(request, self.fields[url_bits[0]], *url_bits[1:])
62 raise http.Http404('The requested page does not exist.')
64 def homepage_view(self, request):
65 easy_model = EasyModel(self.site, self.model)
66 field_list = self.fields.values()
67 field_list.sort(lambda x, y: cmp(x.verbose_name, y.verbose_name))
68 return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list})
70 def field_view(self, request, field, value=None):
71 easy_model = EasyModel(self.site, self.model)
72 easy_field = easy_model.field(field.name)
73 if value is not None:
74 obj_list = easy_model.objects(**{field.name: value})
75 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})
76 obj_list = [v[field.name] for v in self.model._default_manager.distinct().order_by(field.name).values(field.name)]
77 return render_to_response('databrowse/fieldchoice_list.html', {'root_url': self.site.root_url, 'model': easy_model, 'field': easy_field, 'object_list': obj_list})