Django

Code

root/django/branches/gis/django/contrib/databrowse/sites.py

Revision 8215, 5.5 kB (checked in by jbronn, 4 months ago)

gis: Merged revisions 7981-8001,8003-8011,8013-8033,8035-8036,8038-8039,8041-8063,8065-8076,8078-8139,8141-8154,8156-8214 via svnmerge from trunk.

  • Property svn:eol-style set to native
Line 
1 from django import http
2 from django.db import models
3 from django.contrib.databrowse.datastructures import EasyModel
4 from django.shortcuts import render_to_response
5 from django.utils.safestring import mark_safe
6
7 class AlreadyRegistered(Exception):
8     pass
9
10 class NotRegistered(Exception):
11     pass
12
13 class DatabrowsePlugin(object):
14     def urls(self, plugin_name, easy_instance_field):
15         """
16         Given an EasyInstanceField object, returns a list of URLs for this
17         plugin's views of this object. These URLs should be absolute.
18
19         Returns None if the EasyInstanceField object doesn't get a
20         list of plugin-specific URLs.
21         """
22         return None
23
24     def model_index_html(self, request, model, site):
25         """
26         Returns a snippet of HTML to include on the model index page.
27         """
28         return ''
29
30     def model_view(self, request, model_databrowse, url):
31         """
32         Handles main URL routing for a plugin's model-specific pages.
33         """
34         raise NotImplementedError
35
36 class ModelDatabrowse(object):
37     plugins = {}
38
39     def __init__(self, model, site):
40         self.model = model
41         self.site = site
42
43     def root(self, request, url):
44         """
45         Handles main URL routing for the databrowse app.
46
47         `url` is the remainder of the URL -- e.g. 'objects/3'.
48         """
49         # Delegate to the appropriate method, based on the URL.
50         if url is None:
51             return self.main_view(request)
52         try:
53             plugin_name, rest_of_url = url.split('/', 1)
54         except ValueError: # need more than 1 value to unpack
55             plugin_name, rest_of_url = url, None
56         try:
57             plugin = self.plugins[plugin_name]
58         except KeyError:
59             raise http.Http404('A plugin with the requested name does not exist.')
60         return plugin.model_view(request, self, rest_of_url)
61
62     def main_view(self, request):
63         easy_model = EasyModel(self.site, self.model)
64         html_snippets = mark_safe(u'\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()]))
65         return render_to_response('databrowse/model_detail.html', {
66             'model': easy_model,
67             'root_url': self.site.root_url,
68             'plugin_html': html_snippets,
69         })
70
71 class DatabrowseSite(object):
72     def __init__(self):
73         self.registry = {} # model_class -> databrowse_class
74         self.root_url = None
75
76     def register(self, model_or_iterable, databrowse_class=None, **options):
77         """
78         Registers the given model(s) with the given databrowse site.
79
80         The model(s) should be Model classes, not instances.
81
82         If a databrowse class isn't given, it will use DefaultModelDatabrowse
83         (the default databrowse options).
84
85         If a model is already registered, this will raise AlreadyRegistered.
86         """
87         databrowse_class = databrowse_class or DefaultModelDatabrowse
88         if issubclass(model_or_iterable, models.Model):
89             model_or_iterable = [model_or_iterable]
90         for model in model_or_iterable:
91             if model in self.registry:
92                 raise AlreadyRegistered('The model %s is already registered' % model.__class__.__name__)
93             self.registry[model] = databrowse_class
94
95     def unregister(self, model_or_iterable):
96         """
97         Unregisters the given model(s).
98
99         If a model isn't already registered, this will raise NotRegistered.
100         """
101         if issubclass(model_or_iterable, models.Model):
102             model_or_iterable = [model_or_iterable]
103         for model in model_or_iterable:
104             if model not in self.registry:
105                 raise NotRegistered('The model %s is not registered' % model.__class__.__name__)
106             del self.registry[model]
107
108     def root(self, request, url):
109         """
110         Handles main URL routing for the databrowse app.
111
112         `url` is the remainder of the URL -- e.g. 'comments/comment/'.
113         """
114         self.root_url = request.path[:len(request.path) - len(url)]
115         url = url.rstrip('/') # Trim trailing slash, if it exists.
116
117         if url == '':
118             return self.index(request)
119         elif '/' in url:
120             return self.model_page(request, *url.split('/', 2))
121
122         raise http.Http404('The requested databrowse page does not exist.')
123
124     def index(self, request):
125         m_list = [EasyModel(self, m) for m in self.registry.keys()]
126         return render_to_response('databrowse/homepage.html', {'model_list': m_list, 'root_url': self.root_url})
127
128     def model_page(self, request, app_label, model_name, rest_of_url=None):
129         """
130         Handles the model-specific functionality of the databrowse site, delegating
131         to the appropriate ModelDatabrowse class.
132         """
133         model = models.get_model(app_label, model_name)
134         if model is None:
135             raise http.Http404("App %r, model %r, not found." % (app_label, model_name))
136         try:
137             databrowse_class = self.registry[model]
138         except KeyError:
139             raise http.Http404("This model exists but has not been registered with databrowse.")
140         return databrowse_class(model, self).root(request, rest_of_url)
141
142 site = DatabrowseSite()
143
144 from django.contrib.databrowse.plugins.calendars import CalendarPlugin
145 from django.contrib.databrowse.plugins.objects import ObjectDetailPlugin
146 from django.contrib.databrowse.plugins.fieldchoices import FieldChoicePlugin
147
148 class DefaultModelDatabrowse(ModelDatabrowse):
149     plugins = {'objects': ObjectDetailPlugin(), 'calendars': CalendarPlugin(), 'fields': FieldChoicePlugin()}
Note: See TracBrowser for help on using the browser.