仍然最简单的方法是__before_publishing_traverse__
在对象上使用钩子members
:
from zExceptions import Redirect
def __before_publishing_traverse__(self, object, request):
stack = request.TraversalRequestNameStack
if len(stack) > 1 and stack[-2] == 'view':
try:
self.request.form['member_id'] = stack.pop(-1)
if not validate(self.request['member_id']):
raise ValueError
except (IndexError, ValueError):
# missing context or not an integer id; perhaps some URL hacking going on?
raise Redirect(self.absolute_url()) # redirects to `/members`, adjust as needed
该方法在进一步遍历之前由发布者调用;所以发布者已经找到了members
对象,并且这个方法被自己传递(object
)和请求。根据请求,您将找到遍历堆栈;在您的示例情况下,该方法将保留['view', 'isaacnewton']
并且此方法移动'isaacnewton'
到密钥下的请求'member_id'
(在可选验证之后)。
当此方法返回时,发布者将使用剩余的堆栈继续遍历,因此它现在将遍历到view
,它应该是一个浏览器视图,需要member_id
请求中的键。然后它可以完成它的工作:
class MemberView(BrowserView):
def __call__(self):
if 'member_id' in self.request.form: # Huzzah, the traversal worked!