On Dec 11, 2005, at 11:24 AM, reflog wrote:
Hi there.
I've been breaking my head trying to implement a nested urls thingie,
like:
site.com/pages/32/add
where pages would be a result of select, and 32 would link to a
controller of pages.
I tried to do the same thing and came up with this code (as a
modification of the cherrypy recipie found at < http://
www.cherrypy.org/wiki/RestfulResource >).
Essentially, all you need to do is inherit from resource.Resource and
define your own methods that take the 'object' from your model as the
first argument... so, something like:
http://site.com/pages/32/add
would map to:
def add(self, obj):
# where 'obj' here is the actual
# sqlobject instance where ID=32
Also, if 'add' is a POST-able resource, then you can do what I've
done below in the Pages.add method...
(to the list at large) Could we add the resource class as a utility
class in the turbogears distribution (if someone hasn't already done
something similar)? I remember reading on this list, though, that
CherryPy 2.2 might have something like that by default. Is that
correct?
--Tracy
#
# controllers.py
#
import turbogears
import cherrypy
from resource import Resource # see the resource.py code below...
class Pages(Resource):
db_modelname = 'pages'
@turbogears.expose()
def add(self, obj, **kw):
if cherrypy.request.method != 'POST':
raise cherrypy.HTTPError(500, "No you don't...")
# do your pages-specific add work here...
return dict(success=True) # or whatever you want
class Root(controllers.Root):
pages = Pages()
#
# resource.py
#
from sqlobject import SQLObjectNotFound
import turbogears
from turbogears import controllers
import model
class Resource(controllers.Root):
db_modelname = '' # override this in child resources
@turbogears.expose()
def default(self, *vpath, **params):
if not vpath:
return self.index(**params)
# Make a copy of vpath in a list
vpath = list(vpath)
atom = vpath.pop(0)
# See if the first virtual path member is a container action
method = getattr(self, atom, None)
if method and getattr(method, "expose_container"):
return method(*vpath, **params)
# Not a container action; the URI atom must be an existing ID
# Coerce the ID to the correct db type
ID = int(atom)
try:
obj = getattr(model, self.db_modelname).get(ID)
except SQLObjectNotFound:
raise cherrypy.NotFound
# There may be further virtual path components.
# Try to map them to methods in this class.
if vpath:
method = getattr(self, vpath[0], None)
if method and getattr(method, "exposed"):
return method(obj, *vpath[1:], **params)
else:
raise cherrypy.NotFound("We can't %s with %s" %
(`vpath[0]`, obj))
# No further known vpath components. Call a default handler.
return self.show(obj, *vpath, **params)
@turbogears.expose()
def show(self, obj):
raise NotImplemented("you must define your own 'show' method
for your obj...")