Python金字塔遍历

Gin*_*ino 6 python traversal pyramid

我一直在尝试金字塔,这种遍历的事情让我疯了.我基本上摆弄周围做一个购物车的控制面板,这是基本的结构,我的想法.

登录页面

localhost:6543/admin_login
Run Code Online (Sandbox Code Playgroud)

成功登录后

localhost:6543/admin/home 
Run Code Online (Sandbox Code Playgroud)

查看所有现有产品

localhost:6543/admin/product
Run Code Online (Sandbox Code Playgroud)

编辑产品X.

localhost:6543/admin/product/edit/1
Run Code Online (Sandbox Code Playgroud)

所以我的文件夹结构是这样的(大写文件是模型)

  • 我的车
    • resources.py
    • Admin.py
    • Product.py
    • 静态的
    • 模板
    • 意见
      • __init__.py
      • admin.py
      • root.py

我的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
Run Code Online (Sandbox Code Playgroud)

views/__init.py,它只是一个空白文件.至于root.py它,它只是一个httpexceptions.HTTPNOTFOUND404代码

对于 views/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'] )
Run Code Online (Sandbox Code Playgroud)

登录后,我将网址指向localhost:6543/admin/product,我注意到它仍然呈现主页,而不是产品页面.

我知道我错过了一些东西,但我似乎无法找出原因.通过http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/traversal.html,我知道我在正确的轨道上,因为可能有任意段.

我已经尝试将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
Run Code Online (Sandbox Code Playgroud)

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

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

任何帮助将不胜感激.谢谢!

这是我在多年的java之后第一次在python中编码.所以可能有一些我对pyramid/python不熟悉的术语/概念.


好吧,我觉得我有点想要绕过这个遍历的东西.通过http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/narr/traversal.html阅读,有两件事引起了我的注意.

例如,如果路径信息序列是['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.
Run Code Online (Sandbox Code Playgroud)

所以基于localhost:6543/admin/products,view_config的设置如下:

@view_config(context = Admin,name ='products',....)

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

    ## 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
Run Code Online (Sandbox Code Playgroud)

并在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': ''}
Run Code Online (Sandbox Code Playgroud)

不知何故,它不是渲染产品模板,而是默认404.

mad*_*jar 4

您看一下有关遍历的文档,因为您还没有完全正确。本教程对于理解遍历也非常有用。我将尝试根据您的情况进行快速解释:

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

然后,金字塔尝试确定该请求的上下文。为此,它从根(它遍历)开始递归地调用__getitem__(这只是另一种说法object[segment])。在示例中,它执行root['admin'],返回一个管理对象,然后执行admin['product']。当遇到 KeyError 时它会停止。

一旦我们有了上下文,金字塔就会搜索具有该上下文的视图,并且其视图名称是未遍历的部分。例如,如果admin['product']引发 KeyError,则金字塔会查找配置了@view_config(context=Admin, name="product").


那么,如何从中制作一个应用程序呢?首先,您确定您的资源树是什么。在你的情况下,它可能看起来像这样:

    • 行政
      • 产品容器
        • 产品

有一个home以管理上下文命名的视图 ( /admin/home)、一个没有名称的视图ProductContainer( ) 和一个以产品/admin/product命名的视图( )。edit/admin/product/1/edit