11:ルーティングによるビューへのURLのディスパッチ(11: Dispatching URLs To Views With Routing)

ルーティングは受信したURLパターンをビューコードに一致させます。Pyramidのルーティングには多くの便利な機能があります。

背景(Background)

Webアプリケーションの作成は、通常は洗練されたURL設計を意味します。私たちはリクエストとビューのためにPyramidの機能のいくつかを見ただけです。ルーティングに役立つ機能を見てみましょう。

前回はPyramidのビューへのURLのルーティングの基本を見ていました。

  • プロジェクトの「設定」コードはURLの一部と一致するときに使用されるルート名を登録します
  • そのルート名に対してビューが呼び出されるように設定されています。

注釈

なぜ2回設定するのですか?他のPythonWebフレームワークを使用すると、ルートを作成して1つのステップでビューに関連付けできます。経路には相対的な順序が必要 に示すように 、複数のルートが同じURLパターンに一致する可能性があります。推測を支援する方法を提供するのではなくPyramidでは順序を明示できます。Pyramidはこの問題を回避するための設備も提供しています。ピラミッドで暗黙のルート順序を使用するシステムを構築することは比較的簡単です。暗黙のルートに興味があるなら、The Groundhog series of screencasts  を見てください。

目的(Objectives)

  • URLの一部をPythonの辞書型に抽出するルートを定義します。
  • 辞書型のデータをビューで使用します。

手順(steps)

  1. 最初に view_classes の手順の結果をコピーします。

    $ cd ..; cp -r view_classes routing; cd routing
    $ $VENV/bin/pip install -e .
    
  2. Our routing/tutorial/__init__.py needs a route with a replacement pattern:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from pyramid.config import Configurator
    
    
    def main(global_config, **settings):
        config = Configurator(settings=settings)
        config.include('pyramid_chameleon')
        config.add_route('home', '/howdy/{first}/{last}')
        config.scan('.views')
        return config.make_wsgi_app()
    
  3. routing/tutorial/views.py の中でただ一つのビューしか必要としません:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    from pyramid.view import (
        view_config,
        view_defaults
        )
    
    
    @view_defaults(renderer='home.pt')
    class TutorialViews:
        def __init__(self, request):
            self.request = request
    
        @view_config(route_name='home')
        def home(self):
            first = self.request.matchdict['first']
            last = self.request.matchdict['last']
            return {
                'name': 'Home View',
                'first': first,
                'last': last
            }
    
  4. routing/tutorial/home.pt の中でただ一つのビューしか必要としません:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>Quick Tutorial: ${name}</title>
    </head>
    <body>
    <h1>${name}</h1>
    <p>First: ${first}, Last: ${last}</p>
    </body>
    </html>
    
  5. routing/tutorial/tests.py を更新します:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    import unittest
    
    from pyramid import testing
    
    
    class TutorialViewTests(unittest.TestCase):
        def setUp(self):
            self.config = testing.setUp()
    
        def tearDown(self):
            testing.tearDown()
    
        def test_home(self):
            from .views import TutorialViews
    
            request = testing.DummyRequest()
            request.matchdict['first'] = 'First'
            request.matchdict['last'] = 'Last'
            inst = TutorialViews(request)
            response = inst.home()
            self.assertEqual(response['first'], 'First')
            self.assertEqual(response['last'], 'Last')
    
    
    class TutorialFunctionalTests(unittest.TestCase):
        def setUp(self):
            from tutorial import main
            app = main({})
            from webtest import TestApp
    
            self.testapp = TestApp(app)
    
        def test_home(self):
            res = self.testapp.get('/howdy/Jane/Doe', status=200)
            self.assertIn(b'Jane', res.body)
            self.assertIn(b'Doe', res.body)
    
  6. テスト実行します:

    $ $VENV/bin/py.test tutorial/tests.py -q
    ..
    2 passed in 0.39 seconds
    
  7. Pyramidアプリケーションを以下のように実行します:

    $ $VENV/bin/pserve development.ini --reload
    
  8. ブラウザで http://localhost:6543/howdy/amy/smith を開きます。

分析(Analysis)

__init__.py ではルートの宣言での重要な変更を参照してください:

config.add_route('hello', '/howdy/{first}/{last}')

これにより、 configurator に URLに「置換パターン」があることが伝えられます。amy` が``first`` に smithlast に割り当てられてURLが /howdy/amy/smith になります。このデータをビューで使用できます。

self.request.matchdict['first']
self.request.matchdict['last']

request.matchdict  は ルート宣言の 「置換パターン」と一致するURLからの値を含みます。この情報はPyramid内のリクエストにアクセスできる箇所のどこでも使用できます。

エクストラクレジット(Extra credit)

  1. http://localhost:6543/howdy というURLに行くとどうなりますか?これは期待した結果でしょうか?