我认为您缺少的部分是遍历部分。产品是资源吗?好吧,这取决于您的遍历产生了什么,它可以产生产品......
也许最好从视图回到创建应用程序时如何配置它......
这是一个典型的观点。
@view_config(context=Product, permission="view")
def view_product(context, request):
pass # would do stuff
因此,当上下文是 Product 的实例时,会调用此视图。并且如果该实例的acl属性具有“查看”权限。那么 Product 的实例如何成为上下文呢?
这就是遍历的魔力所在。遍历的逻辑就是一本字典。所以这对你有用的一种方法是,如果你有一个像
/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 参数需要一个可调用的,并将当前请求交给它。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()
注意:我从内存中做了代码示例,显然你需要所有必要的导入等。换句话说,这不能作为复制/粘贴工作