durusmail: quixote-users: _get_component must return a publishing object
_get_component must return a publishing object
2003-08-07
2003-08-07
2003-08-07
2003-08-07
_get_component must return a publishing object
Neil Schemenauer
2003-08-07
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

reply