On Thu, Aug 07, 2003 at 01:48:27PM +0400, Oleg Broytmann wrote:
> Hi! Another problem.
>
> My program is publishing objects with URLs like this:
> http://host-ru/files/resources/ID/?page=1
> IDs are pointers to a DB, and must be intergers. There are many IDs, so
> there is no point tu put them into _q_access. The only way to handle them
> is _q_lookup, right?
Yes.
>
> class Resources:
> def _q_lookup(self, request, id):
> try:
> id = int(id)
> except ValueError:
> return request.redirect("http://host-ru/error-page")
_q_lookup must return a namespace. You want something like this:
class Redirector:
_q_exports = []
def __init__(self, path):
self.path = path
def _q_lookup(self, request, component):
return self
def __call__(self, request):
return request.redirect(self.path)
def _q_lookup(self, request, id):
try:
id = int(id)
except ValueError:
return Redirector("http://host-ru/error-page")
_q_lookup hooks into the path traversal process. The Redirector class
needs it's own _q_lookup since you want to consume whatever path is
being traversed and then redirect to an error page.
Rasing a TraversalError exception is another way to do what you want (as
David suggested). Something like:
class Redirect(TraversalError):
def __init__(self, url):
self.url = url
def format(self, request):
request.redirect(self.url)
return 'you should be redirected to %s' % self.url
def _q_lookup(self, request, id):
try:
id = int(id)
except ValueError:
raise Redirect("http://host-ru/error-page")
> The problem is that the loop is continuing to traverse objects even if
> _get_component returned non-traversable object (string, in my case).
> On the next call to _get_component quixote raise an exception "... has
> no _q_exports list". Shouldn't the loop stops after _get_component
> returned non-traversable object?
It would be nice if it was easier to interrupt to traversal process.
Your suggestion doesn't work, I think. Suppose the path "/about" ends
up returning a string via a _q_lookup. If someone tries to access
"/about/some/nonsense" then the "/some/nonsense" part will be consumed
and they will not get a 404 error as they should.
I guess there could be some special wrapper object that _q_lookup could
return to signal that that the traversal should end.
Neil