The _q_lookup() method
Now take a look at the ExtraDirectory class in extras.ptl. This class exhibits some more advanced publishing features. If you look back at the default _q_traverse() implementation (in directory.py), you will see that the _q_traverse does not give up if _q_translate() returns None, indicating that the path component has no designated corresponding attribute name. In this case, _q_traverse() tries calling self._q_lookup() to see if the object of interest can be found in a different way. Note that _q_lookup() takes the component as an argument and must return either (if there is more path to traverse) a Directory instance, or else (if the component is the last in the path) a callable or a string.
In this particular case, the ExtrasDirectory._q_lookup() call returns an instance of IntegerUI (a subclass of Directory). The interest here, unlike the ExtrasDirectory() instance itself, is created on-the-fly during the traversal, especially for this particular component. Try loading http://localhost:8080/extras/12/ to see how this behaves.
Note that the correct URL to get to the IntegerUI(12)._q_index() call ends with a '/'. This can sometimes be confusing to people who expect http://localhost:8080/extras/12 to yield the same page as http://localhost:8080/extras/12/. If given the path ['extras', '12'], the default _q_traverse() ends up calling the instance of IntegerUI. The Directory.__call__() (see directory.py) determines the result: if no form values were submitted and adding a slash would produce a page, the call returns the result of calling quixote.redirect(). The redirect() call here causes the server to issue a permanent redirect response to the path with the slash added. When this automatic redirect is used, a message is printed to the error log. If the conditions for a redirect are not met, the call falls back to raising a TraversalError. [Note, if you don't like this redirect behavior, override, replace, or delete Directory.__call__]
The _q_lookup() pattern is useful when you want to allow URL components that you either don't know or don't want to list in _q_exports ahead of time.
_q_lookup()是ExtraDirectory类的一个方法,代码如下:
return IntegerUI(component)
IntegerUI是一个类,在integers.ptl文件中。它接受一个可以转化为整数的路径组件做参数:
try :
self.n = int(component)
except ValueError, exc:
raise TraversalError(str(exc))
计算阶乘的方法:
if self.n > 10000 :
sys.stderr.write( " warning: possible denial-of-service attack "
" (request for factorial(%d)) " % self.n)
get_response().set_content_type( " text/plain " )
return " %d! = %d " % (self.n, fact(self.n))
上一个数字/下一个数字的方法:
return redirect( " ../%d/ " % (self.n - 1 ))
def next(self):
return redirect( " ../%d/ " % (self.n + 1 ))
_q_exports的内容:
_q_lookup()模板在你想允许事先并不知道或者不想在_q_exports中列出的路径组件时很有用。
注意点:访问时URL末尾的'/'不能少。