7

私はピラミッドを試してきましたが、このトラバーサルは私に夢中です。私は基本的にショッピング カートのコントロール パネルをいじっていますが、これは私が念頭に置いている基本的な構造です。

ログインページ

localhost:6543/admin_login

ログイン成功時

localhost:6543/admin/home 

すべての既存の製品を表示するには

localhost:6543/admin/product

製品 X を編集するには

localhost:6543/admin/product/edit/1

だから私のフォルダ構造はこのようなものです(Capitalizeファイルはモデルです)

  • 私のカート
    • resources.py
    • Admin.py
    • Product.py
    • 静的
    • テンプレート
    • ビュー
      • __init__.py
      • admin.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

ではviews/__init.py、これは単なる空のファイルです。に関してはroot.py、それは単なるhttpexceptions.HTTPNOTFOUND, 404 コードです

為に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'] )

ログイン後、URL を 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

この部分では、コンソールにそれぞれのメッセージが確実に出力されるように、ある程度の進歩を遂げました。ただし、view_configs にどのように接続すればよいか、変更が必要な場合に view_configs のパラメーターをどうするかについては、まったくわかりません。

バージョンが何かに影響するかどうかはわかりませんが、とにかく、私はpython 3.3を使用しています

どんな助けでも大歓迎です。ありがとう!

何年にもわたるJavaの後、Pythonでコーディングするのはこれが初めてです。そのため、ピラミッド/パイソンに関して私がよく知らない用語/概念がいくつかあるかもしれません。


わかりました、私はちょっとこのトラバーサルのことをラップすることに気がついたと思います. http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/narr/traversal.htmlを読んで、2 つのことが気になりました。

たとえば、パス情報のシーケンスが ['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 の設定は次のようになります。

@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

そして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': ''}

どういうわけか、それは製品テンプレートをレンダリングしていませんが、デフォルトの 404 です。

4

2 に答える 2

4

traversal についてのドキュメントを見てみましょう。このチュートリアルは、トラバーサルを理解するのにも非常に役立ちます。私はあなたの文脈で簡単な説明をしようとします:

まず、リクエストのパスがイントロ セグメントに分割されます。たとえば、/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

于 2012-11-20T15:13:19.073 に答える
2

以下のコードがエレガントなのか抜け穴があるのか​​ はわかりませんが、今では間違いなく機能しています。誰かが私のような同じ問題に直面している場合に備えて、私はそれを入れます。

resources.py

    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="**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': ''}
于 2012-11-21T16:13:08.843 に答える