07:带视图的基本Web处理¶
使用装饰器和多个视图组织视图模块。
背景¶
对于目前为止的例子, hello_world
功能是一个“视图”。在Pyramid中,视图是接受Web请求和返回响应的主要方式。
到目前为止,我们的示例将所有内容放在一个文件中:
视图功能
它在配置程序中的注册
将其映射到URL的路由
wsgi应用程序启动程序
让我们将视图移到它们自己的视图中 views.py
模块化并更改启动代码以扫描该模块,查找设置视图的装饰器。我们还要添加第二个视图并更新我们的测试。
目标¶
将视图移动到配置程序扫描的模块中。
创建进行声明性配置的装饰器。
步骤¶
让我们首先使用前一个包作为新分发的起点,然后使其处于活动状态:
cd ..; cp -r functional_testing views; cd views $VENV/bin/pip install -e .
我们的
views/tutorial/__init__.py
缩短了很多:1from pyramid.config import Configurator 2 3 4def main(global_config, **settings): 5 config = Configurator(settings=settings) 6 config.add_route('home', '/') 7 config.add_route('hello', '/howdy') 8 config.scan('.views') 9 return config.make_wsgi_app()
让我们添加一个模块
views/tutorial/views.py
重点处理请求和响应:1from pyramid.response import Response 2from pyramid.view import view_config 3 4 5# First view, available at http://localhost:6543/ 6@view_config(route_name='home') 7def home(request): 8 return Response('<body>Visit <a href="/howdy">hello</a></body>') 9 10 11# /howdy 12@view_config(route_name='hello') 13def hello(request): 14 return Response('<body>Go back <a href="/">home</a></body>')
更新测试以涵盖两个新视图:
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 home 15 16 request = testing.DummyRequest() 17 response = home(request) 18 self.assertEqual(response.status_code, 200) 19 self.assertIn(b'Visit', response.body) 20 21 def test_hello(self): 22 from .views import hello 23 24 request = testing.DummyRequest() 25 response = hello(request) 26 self.assertEqual(response.status_code, 200) 27 self.assertIn(b'Go back', response.body) 28 29 30class TutorialFunctionalTests(unittest.TestCase): 31 def setUp(self): 32 from tutorial import main 33 app = main({}) 34 from webtest import TestApp 35 36 self.testapp = TestApp(app) 37 38 def test_home(self): 39 res = self.testapp.get('/', status=200) 40 self.assertIn(b'<body>Visit', res.body) 41 42 def test_hello(self): 43 res = self.testapp.get('/howdy', status=200) 44 self.assertIn(b'<body>Go back', res.body)
现在运行测试:
$VENV/bin/pytest tutorial/tests.py -q .... 4 passed in 0.28 seconds
运行 Pyramid 应用程序时使用:
$VENV/bin/pserve development.ini --reload
在浏览器中打开http://localhost:6543/和http://localhost:6543/howdy。
分析¶
我们添加了更多的URL,但也从中删除了应用程序启动代码中的视图代码。 tutorial/__init__.py
. 我们的视图及其视图注册(通过装饰器)现在位于一个模块中 views.py
,通过扫描 config.scan('.views')
.
我们有两种观点,每一种观点都是相互引导的。如果从http://localhost:6543/开始,将得到一个响应,其中包含指向下一个视图的链接。这个 hello
视图(在URL上可用 /howdy
)有返回第一个视图的链接。
此步骤还显示URL中显示的名称、将URL映射到视图的“路由”的名称以及视图的名称都可能不同。更多关于路线的信息。
早些时候我们看到 config.add_view
作为配置视图的一种方法。本节介绍 @view_config
. Pyramid的配置支持 imperative configuration ,比如 config.add_view
在上一个示例中。您也可以使用 declarative configuration ,其中一条 Python decorator 放置在视图上方的行上。这两种方法都会产生相同的最终配置,因此,这通常只是一个简单的品味问题。
额外credit¶
圆点在哪
.views
意味着?为什么可能
assertIn
在测试响应中的文本时,比assertEqual
是吗?