あなたが欠けている部分はトラバーサル部分だと思います。製品はリソースですか? それはあなたのトラバーサルが何を生成するかに依存します.それは製品を生成する可能性があります.....
おそらく、ビューから、アプリケーションの作成時にどのように構成されるかまで、これを説明するのが最善かもしれません...
これが典型的なビューです。
@view_config(context=Product, permission="view")
def view_product(context, request):
pass # would do stuff
したがって、コンテキストが Product のインスタンスである場合、このビューが呼び出されます。かつ、そのインスタンスのacl属性に「表示」権限がある場合。では、Product のインスタンスはどのようにしてコンテキストになるのでしょうか?
ここで、トラバーサルの魔法の出番です。トラバーサルのロジックそのものは、単なる辞書の辞書です。したがって、これが機能する1つの方法は、次のようなURLがある場合です
/product/1
どういうわけか、ビューを決定できるようにコンテキストを決定するために、URL のセグメントによって一部のリソースをトラバースする必要があります。次のようなものがあるとしたら...
class ProductContainer(object):
"""
container = ProductContainer()
container[1]
>>> <Product(1)>
"""
def __init__(self, request, name="product", parent=None):
self.__name__ = name
self.__parent__ = parent
self._request = request
def __getitem__(self, key):
p = db.get_product(id=key)
if not p:
raise KeyError(key)
else:
p.__acl__ = [(Allow, Everyone,"view")]
p.__name__ = key
p.__parent__ = self
return p
現在、これはドキュメントでカバーされており、知っておく必要のある基本に要約しようとしています。ProductContainer は、辞書のように動作するオブジェクトです。URL 生成メソッドが正しく機能するためには、「name 」属性と「parent 」属性がピラミッドに必要です。
これで、トラバースできるリソースができました。ピラミッドに ProductContainer をトラバースするように指示するにはどうすればよいでしょうか? これは Configurator オブジェクトを介して行います。
config = Configurator()
config.add_route(name="product",
path="/product/*traverse",
factory=ProductContainer)
config.scan()
application = config.make_wsgi_app()
factory パラメーターは callable を想定し、現在のリクエストを渡します。ProductContainer. initはそれを問題なく行います。
これは、このような単純な例では少し多すぎるように思えるかもしれませんが、可能性を想像していただければ幸いです。このパターンにより、非常に細かい権限モデルが可能になります。
行レベルの ACL などの非常に細かいパーミッション モデルが必要ない場合は、おそらくトラバーサルは必要ありません。代わりに、単一のルート ファクトリでルートを使用できます。
class RootFactory(object):
def __init__(self, request):
self._request = request
self.__acl__ = [(Allow, Everyone, "view")] # todo: add more acls
@view_config(permission="view", route_name="orders")
def view_product(context, request):
order_id, product_id = request.matchdict["order_id"], request.matchdict["product_id"]
pass # do what you need to with the input, the security check already happened
config = Configurator(root_factory=RootFactory)
config.add_route(name="orders",
path="/order/{order_id}/products/{product_id}")
config.scan()
application = config.make_wsgi_app()
注: 私はメモリからコード例を作成しました。明らかに、必要なすべてのインポートなどが必要です。つまり、これはコピー/貼り付けとして機能しません。