2012-03-02 89 views
9

我一直在閱讀如何對新創建的Pyramid應用程序實施授權(和身份驗證)的方法。我不斷碰到名爲「資源」的概念。我在我的應用程序中使用python-couchdb,根本不使用RDBMS,因此沒有使用SQLAlchemy。如果我創建一個產品對象,如下所示:金字塔資源:簡單英語

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> 

如果我還用穿越,這是不是意味着我在我的python-CouchDB中添加的GetItem功能產品類/資源?

對不起,這只是真的混淆了所有的新術語(我來自Pylons 0.9.7)。

在此先感謝。

回答

6

我認爲你缺少的部分是遍歷部分。是產品 的資源?那麼這取決於你遍歷產生,它 能生產的產品.....

也許它可能是最好從視圖中穿行這回 創建應用程序時,它被如何配置的是什麼?

這是一個典型的視圖。

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

所以這個視圖在上下文是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生成 方法正常工作。

所以現在我們有一個可以遍歷的資源。我們如何告訴 金字塔來遍歷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() 

注:我沒有從內存中的代碼示例,顯然你需要的所有必需的進口等。這不會是一個複製/粘貼

+0

該死......我還是無法把握這個抽象概念。 __name__值是否必須與config.add_route(name =「」)中的值相同?那麼Traversal如何確定匹配傳入URL(如/ photo/1)時使用哪個資源?我可以嘗試說明我的應用程序的一個例子嗎?我的應用程序處理產品訂單。每個訂單可能有一個或多個產品。這是否意味着應將__parent__屬性設置爲Order資源,並且__name__屬性應該是產品資源的名稱? – Mark 2012-03-03 10:29:12

+0

對不起,以上內容不夠長。看一下ProductConatiner,就像文檔中提到的「工廠」一樣嗎?這是否意味着我必須爲每個資源創建一個工廠,因爲我的資源很可能是名爲Product的python-couchdb對象? – Mark 2012-03-03 10:30:46

+0

add_route中的名稱必須對系統中的所有路由都是唯一的。但它不必匹配路徑中的段。我可以把它命名爲「產品」。 – 2012-03-03 13:51:24