Python金字塔遍历

Python金字塔遍历,python,pyramid,traversal,Python,Pyramid,Traversal,我一直在尝试金字塔,这个穿越的东西让我发疯。我基本上是在摆弄一个购物车的控制面板,这是我心目中的基本结构 登录页面 localhost:6543/admin_login 成功登录后 localhost:6543/admin/home 查看所有现有产品 localhost:6543/admin/product 编辑产品X的步骤 localhost:6543/admin/product/edit/1 所以我的文件夹结构是这样的(大写文件是模型) 我的购物车 资源.py 管理员 Prod

我一直在尝试金字塔,这个穿越的东西让我发疯。我基本上是在摆弄一个购物车的控制面板,这是我心目中的基本结构

登录页面

localhost:6543/admin_login
成功登录后

localhost:6543/admin/home 
查看所有现有产品

localhost:6543/admin/product
编辑产品X的步骤

localhost:6543/admin/product/edit/1
所以我的文件夹结构是这样的(大写文件是模型)

  • 我的购物车
    • 资源.py
    • 管理员
    • Product.py
    • 静止的
    • 模板
    • 观点
      • __初始值
      • 管理员
      • root.py
我的资源.py

    from pyramid.security import Authenticated
    from pyramid.security import Allow
    from pyramid.response import Response

    class Root(object):
       __name__ = ''
       __parent__ = None

       def __init__(self, request):
          pass

       def __getitem__(self, key):

           if key == 'admin_login':
              return Admin()

           elif key == 'admin':
              return Admin()

           raise KeyError

    class Admin(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
           pass
    ## class Root(object):
       ....


    class ProductName(object):
        def __init__(self, _key):
            pass

    class Products(object):
        __name__ = ''
        __parent__ = Root


        def __init__(self):
            pass

        def __getitem__(self, key):
            print ('products: ', key)
            if key == 'add':
                return ProductName(key)

            print ('Approaching KeyError')
            raise KeyError


     class Admin(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
            pass


        def __getitem__(self, key):

            if key == 'products':
               print ('admin: ', key)
               return Products()

            raise KeyError
    class ProductName(object):
        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self, _key):
            pass

    class Products(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
            pass

        def __getitem__(self, key):
            print ('products: ' + key)
            if key == 'add':
               return ProductName(key)

            print ('Approaching KeyError')
            raise KeyError
views/\uu init.py
中,它只是一个空白文件。 至于
root.py
,它只是一个
httpexceptions.HTTPNOTFOUND
,404代码

对于
视图/admin.py

    from pyramid.view import view_config, render_view
    import mycart.resources

    from pyramid.httpexceptions import HTTPNotFound, HTTPFound
    from mycart.views.root import strip_tags
    from pyramid_mailer import get_mailer
    from pyramid_mailer.message import Message

    from pyramid.security import remember , forget , authenticated_userid

    from pyramid.events import subscriber , BeforeRender

    from mycart.Admin import Admin
    from mycart.Product import Product


    @view_config(context='mycart:resources.Admin',   request_method='POST', renderer='admin/login.jinja2')
    def login_post(context, request):

      if 'btnLogin' in request.params:
        token = request.session.get_csrf_token()
        login = request.params['txtLogin']
        password = request.params['txtPassword']

        admin = Admin(login, request)

        if admin.validate_user( password):

            record = admin.find_user_by_login( login )

            request.session['bs_admin_id'] = str(record['_id'])
            request.session['bs_admin_name'] = record['usr']['fname'] + ' ' + record['usr']['lname'];
            request.session['bs_admin_type'] = record['usr']['type']
            headers = remember(request, login )
            return HTTPFound('/admin/home',  headers=headers)

        message = 'Failed login'

      return {'message': message,  'url': '/admin_login', 'page_title': 'Failed Login'}


      @view_config(context='mycart:resources.Admin', name="home", renderer='admin/home.jinja2', permission='admin')
      def home(context, request):
          logged_in = authenticated_userid(request)
          url = request.path_info

          admin = Admin( logged_in, request )
          rec = admin.find_user_by_objectid( request.session['bs_admin_id'] ) ;

          return { 'firstname': rec['usr']['fname']  }


     @view_config(context='mycart:resources.Admin', name="product", renderer='admin/product_listing.jinja2', permission='admin')
          def product_list(context, request):
          print ('yes, showing product listing requested by ', request.session['bs_admin_id'] )
登录后,我将url指向localhost:6543/admin/product,我注意到它仍然呈现主页,而不是产品页面

我知道我错过了一些东西,但我似乎不知道为什么。纵观全局,我知道我在正确的轨道上,因为可能会有任意的部分

我已尝试将resources.py修改为以下内容

   .....

   class Admin(object):

       __name__ = ''
       __parent__ = Root
       __acl__ = [(Allow, Authenticated, 'admin')]

       def __init__(self):
           pass

       def __getitem__(self, key):

          if key == 'product':
             print ("WOOT! Listing products")
             ## this is the part where I don't know what should I return or set or how should I hook it up with view_config

          if key == 'home':
             print ("yes, I'm home!")
             ## this is the part where I don't know what should I return or set or how should I hook it up with view_config

          raise KeyError
对于这一部分,我取得了一些进展,它肯定会在控制台中打印相应的消息。但是,如果需要进行任何更改,我不知道应该如何将其与view\u configs连接起来,以及view\u configs的参数应该是什么

我不知道版本是否会影响任何东西,但无论如何,我使用的是python 3.3

任何帮助都将不胜感激。谢谢

这是我在使用java多年后第一次用python编写代码。因此,关于pyramid/python,可能有一些术语/概念我并不熟悉


好吧,我想我有点想绕着这个遍历的东西。通读一遍,有两件事引起了我的注意

例如,如果路径信息序列为['a','b','c']:

- Traversal starts by acquiring the root resource of the application by calling the root   factory. The root factory can be configured to return whatever object is appropriate as the traversal root of your application.

- Next, the first element ('a') is popped from the path segment sequence and is used as a key to lookup the corresponding resource in the root. This invokes the root resource’s __getitem__ method using that value ('a') as an argument.

- If the root resource “contains” a resource with key 'a', its __getitem__ method will return it. The context temporarily becomes the “A” resource.
因此,基于localhost:6543/admin/products,view_config的设置如下所示:

@查看配置(context=Admin,name='products',…)

所以在对resources.py进行更改之后

    from pyramid.security import Authenticated
    from pyramid.security import Allow
    from pyramid.response import Response

    class Root(object):
       __name__ = ''
       __parent__ = None

       def __init__(self, request):
          pass

       def __getitem__(self, key):

           if key == 'admin_login':
              return Admin()

           elif key == 'admin':
              return Admin()

           raise KeyError

    class Admin(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
           pass
    ## class Root(object):
       ....


    class ProductName(object):
        def __init__(self, _key):
            pass

    class Products(object):
        __name__ = ''
        __parent__ = Root


        def __init__(self):
            pass

        def __getitem__(self, key):
            print ('products: ', key)
            if key == 'add':
                return ProductName(key)

            print ('Approaching KeyError')
            raise KeyError


     class Admin(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
            pass


        def __getitem__(self, key):

            if key == 'products':
               print ('admin: ', key)
               return Products()

            raise KeyError
    class ProductName(object):
        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self, _key):
            pass

    class Products(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
            pass

        def __getitem__(self, key):
            print ('products: ' + key)
            if key == 'add':
               return ProductName(key)

            print ('Approaching KeyError')
            raise KeyError
和在views/admin.py中

    @view_config(context=Admin, name='products',  renderer='admin/products.jinja2', permission = 'admin')
    def product_add(context, request):
        print 'hey products_add'
        return { 'msg': ''}
    @view_config(context="**mycart:resources.ProductName**",  name="",     renderer='admin/product_add.jinja2', permission = 'admin')
        def product_add(context, request):
        print 'hey product add'
        return { 'msg': ''}

    @view_config(context="**mycart:resources.Products**", name='' , renderer='admin/product.jinja2', permission = 'admin')
    def product(context, request):
        print 'hey products listing'
        return { 'msg': ''}
不知何故,或者更确切地说,它不是呈现产品模板,而是呈现默认的404。

您可以查看一下,因为您没有完全正确地呈现产品模板。在理解遍历时也非常有用。我将尝试在您的上下文中做一个快速解释:

首先,请求的路径是分割介绍段。例如,
/admin/product
被分为
['admin','product']

然后,pyramid尝试确定此请求的上下文。为此,它递归地调用
\uuu getitem\uuu
(这只是说它从根(它遍历的)每个段执行
对象[段]
)。在本例中,它执行
root['admin']
,返回一个admin对象,然后执行
admin['product']
。当遇到键错误时,它停止

一旦我们有了一个上下文,pyramid就会用这个上下文搜索一个视图,它的视图名是未被遍历的部分。例如,如果
admin['product']
引发一个键错误,则pyramid将查找配置了
@view\u config(context=admin,name=“product”)
的视图


那么,你如何从中制作应用程序呢?首先,确定什么是资源树。在您的情况下,它可能如下所示:

    • 管理员
      • 产品容器
        • 产品

对于管理上下文(
/Admin/home
),有一个名为
home
的视图(
/Admin/product
),一个名为
的视图(
/Admin/product/1/edit
),一个名为
的视图(
/Admin/product/1/edit
)。虽然我不知道下面的代码是否优雅或有漏洞,它现在肯定对我有用。我会把它放进去,以防有人和我一样面临同样的问题

资源.py

    from pyramid.security import Authenticated
    from pyramid.security import Allow
    from pyramid.response import Response

    class Root(object):
       __name__ = ''
       __parent__ = None

       def __init__(self, request):
          pass

       def __getitem__(self, key):

           if key == 'admin_login':
              return Admin()

           elif key == 'admin':
              return Admin()

           raise KeyError

    class Admin(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
           pass
    ## class Root(object):
       ....


    class ProductName(object):
        def __init__(self, _key):
            pass

    class Products(object):
        __name__ = ''
        __parent__ = Root


        def __init__(self):
            pass

        def __getitem__(self, key):
            print ('products: ', key)
            if key == 'add':
                return ProductName(key)

            print ('Approaching KeyError')
            raise KeyError


     class Admin(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
            pass


        def __getitem__(self, key):

            if key == 'products':
               print ('admin: ', key)
               return Products()

            raise KeyError
    class ProductName(object):
        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self, _key):
            pass

    class Products(object):

        __name__ = ''
        __parent__ = Root
        __acl__ = [(Allow, Authenticated, 'admin')]

        def __init__(self):
            pass

        def __getitem__(self, key):
            print ('products: ' + key)
            if key == 'add':
               return ProductName(key)

            print ('Approaching KeyError')
            raise KeyError
视图/admin.py

    @view_config(context=Admin, name='products',  renderer='admin/products.jinja2', permission = 'admin')
    def product_add(context, request):
        print 'hey products_add'
        return { 'msg': ''}
    @view_config(context="**mycart:resources.ProductName**",  name="",     renderer='admin/product_add.jinja2', permission = 'admin')
        def product_add(context, request):
        print 'hey product add'
        return { 'msg': ''}

    @view_config(context="**mycart:resources.Products**", name='' , renderer='admin/product.jinja2', permission = 'admin')
    def product(context, request):
        print 'hey products listing'
        return { 'msg': ''}

好的,那么子路径的视图配置的输出呢?这是我面临的主要问题。不幸的是,梅里克尔的教程对我来说毫无意义。然而,不知何故,金字塔并没有呈现产品模板。我已经修改了我的问题。。。也许my resources.py的结构错误?您必须确保,对于每个对象,
\uu getitem\uuu
将返回遍历中的下一个对象。你没有包含Root的代码,所以问题可能就在那里。太好了!您可能可以从视图配置中删除
name='
,因为这些是默认值。不过,您的
\uuuuu name\uuuuuuuuu
\uuuuuuuuuuuuuuu
是错误的。名称必须等于指向该对象的url部分(如果您在url/Admin处获得管理对象,则名称必须为Admin),并且父项必须是直接父项(ProductName的父项是产品)。这些用于使用
resource\u url
生成url,如果它们是错误的,则生成的url将是错误的。哈哈哈,是的,我也在摆弄其他子路径,并意识到了这个错误,最后在尝试在此处发送垃圾邮件以获取更多帮助之前修复了它。但是谢谢你提醒我这个错误=D@madjar另一方面,我在考虑root_工厂,并想知道当项目开始扩大时,为不同的部件建立多个工厂是否更容易管理/更优雅。性能方面,这可能是一种更好的做法。在维护方面,哪一种可能是更好的做法?我相信,将单个遍历树直接映射到URL将比遍历/调度混合方式更易于管理。我不认为在绩效方面存在任何有意义的差异,但这可能需要一个基准来确认。至于优雅,请记住,元素的遍历