1

パスの一部がコードによって処理される「仮想」フォルダーを実装する単純なZope2製品を作成したいと思います。フォームのURI

/members/$id/view

例えば

/members/isaacnewton/view

/ membersオブジェクトのコード、つまり。のようなメソッドで処理する必要がありますmembers.view(id='isaacnewton')

Zope TTW Pythonスクリプトにはtraverse_subpathありますが、製品コードでこれを行う方法がわかりません。

私はIPublishTraverseインターフェースを見てきましたpublishTraverse()が、それは非常に一般的なようです。

もっと簡単な方法はありますか?

4

1 に答える 1

2

それでも最も簡単な方法は、オブジェクトの__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!
于 2013-02-07T21:34:35.313 に答える