Mar*_*ark 9 python pyramid couchdb-python
我一直在阅读有关实现授权(和身份验证)到我新创建的Pyramid应用程序的方法.我不断碰到名为"资源"的概念.我在我的应用程序中使用python-couchdb而根本不使用RDBMS,因此没有SQLAlchemy.如果我像这样创建一个Product对象:
class Product(mapping.Document):
item = mapping.TextField()
name = mapping.TextField()
sizes = mapping.ListField()
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我这是否也被称为资源?我一直在阅读金字塔的整个文档,但没有在哪里用简单的英语解释术语资源(也许我只是愚蠢).如果这是资源,这是否意味着我只是将我的ACL内容粘贴在这里:
class Product(mapping.Document):
__acl__ = [(Allow, AUTHENTICATED, 'view')]
item = mapping.TextField()
name = mapping.TextField()
sizes = mapping.ListField()
def __getitem__(self, key):
return <something>
Run Code Online (Sandbox Code Playgroud)
如果我也使用Traversal,这是否意味着我在我的python-couchdb产品类/资源中添加了getitem函数?
对不起,这真的让所有新条款感到困惑(我来自Pylons 0.9.7).
提前致谢.
我认为你缺少的那部分是遍历部分.产品是资源吗?那取决于你的遍历产生了什么,它可以生产产品......
也许最好从视图中回过头来讨论创建应用程序时如何配置它...
这是一个典型的观点.
@view_config(context=Product, permission="view")
def view_product(context, request):
pass # would do stuff
Run Code Online (Sandbox Code Playgroud)
因此,当context是Product的实例时,将调用此视图.AND如果该实例的acl属性具有"view"权限.那么Product的实例将如何成为上下文?
这就是遍历的魔力所在.遍历的逻辑只是一本字典词典.所以这对你有用的一种方法就是如果你有一个像这样的网址
/product/1
Run Code Online (Sandbox Code Playgroud)
不知何故,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
Run Code Online (Sandbox Code Playgroud)
现在这已经在文档中介绍了,我试图将其归结为您需要了解的基础知识.ProductContainer是一个行为类似于字典的对象.金字塔需要" name "和" parent "属性,以便url生成方法正常工作.
所以现在我们有了一个可以遍历的资源.我们如何告诉金字塔遍历ProductContainer?我们通过Configurator对象来做到这一点.
config = Configurator()
config.add_route(name="product",
path="/product/*traverse",
factory=ProductContainer)
config.scan()
application = config.make_wsgi_app()
Run Code Online (Sandbox Code Playgroud)
工厂参数需要一个可调用的并且它将当前请求交给它.碰巧就是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()
Run Code Online (Sandbox Code Playgroud)
注意:我从内存中做了代码示例,显然你需要所有必要的导入等等,换句话说,这不能用作复制/粘贴