金字塔资源:用简单的英语

时间:2012-03-02 20:09:36

标签: python pyramid couchdb-python

我一直在阅读如何在我新创建的Pyramid应用程序中实现授权(和身份验证)。我不断碰到名为“资源”的概念。我在我的应用程序中使用python-couchdb而根本不使用RDBMS,因此没有SQLAlchemy。如果我像这样创建一个Product对象:

class Product(mapping.Document):
  item = mapping.TextField()
  name = mapping.TextField()
  sizes = mapping.ListField()

有人可以告诉我这是否也被称为资源?我一直在阅读金字塔的整个文档,但没有在哪里用简单的英语解释术语资源(也许我只是愚蠢)。如果这是资源,这是否意味着我只是像这样坚持我的ACL内容:

class Product(mapping.Document):
  __acl__ = [(Allow, AUTHENTICATED, 'view')]
  item = mapping.TextField()
  name = mapping.TextField()
  sizes = mapping.ListField()

  def __getitem__(self, key):
      return <something>

如果我还要使用Traversal,这是否意味着我在我的python-couchdb产品类/资源中添加 getitem 函数?

对不起,这真的让所有新条款感到困惑(我来自Pylons 0.9.7)。

提前致谢。

2 个答案:

答案 0 :(得分:6)

我认为你缺少的那部分是遍历部分。是产品 资源?那取决于你的遍历产生了什么 可以生产产品......

也许最好从视图中回过头来看看 如何在创建应用程序时配置它......

这是一个典型的观点。

  @view_config(context=Product, permission="view")
  def view_product(context, request):
      pass # would do stuff  

因此,当context是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是一个对象 这个行为就像一本字典。 “名称”和“父级” 为了生成网址,金字塔需要属性 工作正确的方法。

所以现在我们有了一个可以遍历的资源。我们怎么说 金字塔遍历ProductContainer?我们通过这样做 配置器对象。

  config = Configurator()
  config.add_route(name="product",
                   path="/product/*traverse",
                   factory=ProductContainer)
  config.scan()
  application = config.make_wsgi_app()

工厂参数需要一个可调用的,并将其交给当前 请求。碰巧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()

注意:我从内存中做了代码示例,显然你需要所有必要的导入等等,换句话说,这不会起到复制/粘贴的作用

答案 1 :(得分:0)

你有没有完成http://michael.merickel.org/projects/pyramid_auth_demo/的工作?如果没有,我怀疑它可能会有所帮助。最后一节http://michael.merickel.org/projects/pyramid_auth_demo/object_security.html实现了您所追求的模式(注意示例“模型”类继承的内容不比object更复杂。)