11:通过路由将URL发送到视图

路由匹配传入的URL模式以查看代码。Pyramid的路由有许多有用的功能。

背景

编写Web应用程序通常意味着复杂的URL设计。我们刚刚看到一些Pyramid的请求和意见。让我们看看有助于路由的功能。

以前,我们看到了将URL路由到Pyramid中的视图的基本知识。

  • 项目的“设置”代码注册一个路由名称,以便在匹配URL的一部分时使用。

  • 在其他地方,视图被配置为调用该路由名称。

备注

为什么要这样做两次?其他的PythonWeb框架允许您创建一个路由,并在一个步骤中将其与视图关联。如中所示 路由需要相对排序 ,多个路由可能匹配相同的URL模式。金字塔并没有提供帮助猜测的方法,而是让您在排序时更加明确。金字塔还提供了避免这个问题的设施。构建一个使用金字塔隐式路径排序的系统相对容易。见 The Groundhog series of screencasts 如果你有兴趣的话。

目标

  • 定义将URL的一部分提取到Python字典中的路由。

  • 在视图中使用字典数据。

步骤

  1. 首先我们复制 view_classes 步骤:

    cd ..; cp -r view_classes routing; cd routing
    $VENV/bin/pip install -e .
    
  2. 我们的 routing/tutorial/__init__.py 需要具有替换模式的路由:

    1from pyramid.config import Configurator
    2
    3
    4def main(global_config, **settings):
    5    config = Configurator(settings=settings)
    6    config.include('pyramid_chameleon')
    7    config.add_route('home', '/howdy/{first}/{last}')
    8    config.scan('.views')
    9    return config.make_wsgi_app()
    
  3. 我们只需要一个视野 routing/tutorial/views.py

     1from pyramid.view import (
     2    view_config,
     3    view_defaults
     4    )
     5
     6
     7@view_defaults(renderer='home.pt')
     8class TutorialViews:
     9    def __init__(self, request):
    10        self.request = request
    11
    12    @view_config(route_name='home')
    13    def home(self):
    14        first = self.request.matchdict['first']
    15        last = self.request.matchdict['last']
    16        return {
    17            'name': 'Home View',
    18            'first': first,
    19            'last': last
    20        }
    
  4. 我们只需要一个视野 routing/tutorial/home.pt

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

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

    $VENV/bin/pytest 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。

分析

__init__.py 我们看到我们的路线声明发生了重大变化:

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

用这个我们告诉 configurator 我们的URL有一个“替换模式”。使用此,URL如 /howdy/amy/smith 将分配 amyfirstsmithlast . 然后我们可以在我们的视图中使用这些数据:

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

request.matchdict 包含URL中与路由声明中的“替换模式”(大括号)匹配的值。这些信息可以在Pyramid中任何可以访问请求的地方使用。

额外credit

  1. 如果您转到url http://localhost:6543/howdy,会发生什么?这是你期望的结果吗?