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
7 class AlreadyRegistered(Exception):
10 class NotRegistered(Exception):
13 class DatabrowsePlugin(object):
14 def urls(self
, plugin_name
, easy_instance_field
):
16 Given an EasyInstanceField object, returns a list of URLs for this
17 plugin's views of this object. These URLs should be absolute.
19 Returns None if the EasyInstanceField object doesn't get a
20 list of plugin-specific URLs.
24 def model_index_html(self
, request
, model
, site
):
26 Returns a snippet of HTML to include on the model index page.
30 def model_view(self
, request
, model_databrowse
, url
):
32 Handles main URL routing for a plugin's model-specific pages.
34 raise NotImplementedError
36 class ModelDatabrowse(object):
39 def __init__(self
, model
, site
):
43 def root(self
, request
, url
):
45 Handles main URL routing for the databrowse app.
47 `url` is the remainder of the URL -- e.g. 'objects/3'.
49 # Delegate to the appropriate method, based on the URL.
51 return self
.main_view(request
)
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
57 plugin
= self
.plugins
[plugin_name
]
59 raise http
.Http404('A plugin with the requested name does not exist.')
60 return plugin
.model_view(request
, self
, rest_of_url
)
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', {
67 'root_url': self
.site
.root_url
,
68 'plugin_html': html_snippets
,
71 class DatabrowseSite(object):
73 self
.registry
= {} # model_class -> databrowse_class
76 def register(self
, *model_list
, **options
):
78 Registers the given model(s) with the given databrowse site.
80 The model(s) should be Model classes, not instances.
82 If a databrowse class isn't given, it will use DefaultModelDatabrowse
83 (the default databrowse options).
85 If a model is already registered, this will raise AlreadyRegistered.
87 databrowse_class
= options
.pop('databrowse_class', DefaultModelDatabrowse
)
88 for model
in model_list
:
89 if model
in self
.registry
:
90 raise AlreadyRegistered('The model %s is already registered' % model
.__name
__)
91 self
.registry
[model
] = databrowse_class
93 def unregister(self
, *model_list
):
95 Unregisters the given model(s).
97 If a model isn't already registered, this will raise NotRegistered.
99 for model
in model_list
:
100 if model
not in self
.registry
:
101 raise NotRegistered('The model %s is not registered' % model
.__name
__)
102 del self
.registry
[model
]
104 def root(self
, request
, url
):
106 Handles main URL routing for the databrowse app.
108 `url` is the remainder of the URL -- e.g. 'comments/comment/'.
110 self
.root_url
= request
.path
[:len(request
.path
) - len(url
)]
111 url
= url
.rstrip('/') # Trim trailing slash, if it exists.
114 return self
.index(request
)
116 return self
.model_page(request
, *url
.split('/', 2))
118 raise http
.Http404('The requested databrowse page does not exist.')
120 def index(self
, request
):
121 m_list
= [EasyModel(self
, m
) for m
in self
.registry
.keys()]
122 return render_to_response('databrowse/homepage.html', {'model_list': m_list
, 'root_url': self
.root_url
})
124 def model_page(self
, request
, app_label
, model_name
, rest_of_url
=None):
126 Handles the model-specific functionality of the databrowse site, delegating
127 to the appropriate ModelDatabrowse class.
129 model
= models
.get_model(app_label
, model_name
)
131 raise http
.Http404("App %r, model %r, not found." % (app_label
, model_name
))
133 databrowse_class
= self
.registry
[model
]
135 raise http
.Http404("This model exists but has not been registered with databrowse.")
136 return databrowse_class(model
, self
).root(request
, rest_of_url
)
138 site
= DatabrowseSite()
140 from django
.contrib
.databrowse
.plugins
.calendars
import CalendarPlugin
141 from django
.contrib
.databrowse
.plugins
.objects
import ObjectDetailPlugin
142 from django
.contrib
.databrowse
.plugins
.fieldchoices
import FieldChoicePlugin
144 class DefaultModelDatabrowse(ModelDatabrowse
):
145 plugins
= {'objects': ObjectDetailPlugin(), 'calendars': CalendarPlugin(), 'fields': FieldChoicePlugin()}