10:处理Web请求和响应¶
Web应用程序处理传入请求并返回传出响应。Pyramid使处理请求和响应变得方便和可靠。
目标¶
了解Pyramid对请求和响应的选择的背景。
从请求中获取数据。
更改响应头中的信息。
背景¶
为Web开发意味着处理Web请求。由于这是Web应用程序的关键部分,因此Web开发人员需要一套健壮、成熟的软件来处理Web请求并返回Web响应。
Pyramid一直很好地适应了现有的python web开发世界(虚拟环境、打包、cookiecutters、首先使用python 3等等)。Pyramid变成了著名的 WebOb 用于请求和响应处理的python库。在上面的例子中,Pyramid手 hello_world
一 request
那就是 based on WebOb .
步骤¶
首先我们复制
view_classes
步骤:cd ..; cp -r view_classes request_response; cd request_response $VENV/bin/pip install -e .
简化
request_response/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('plain', '/plain') 8 config.scan('.views') 9 return config.make_wsgi_app()
我们只需要一个视野
request_response/tutorial/views.py
:1from pyramid.httpexceptions import HTTPFound 2from pyramid.response import Response 3from pyramid.view import view_config 4 5 6class TutorialViews: 7 def __init__(self, request): 8 self.request = request 9 10 @view_config(route_name='home') 11 def home(self): 12 return HTTPFound(location='/plain') 13 14 @view_config(route_name='plain') 15 def plain(self): 16 name = self.request.params.get('name', 'No Name Provided') 17 18 body = 'URL %s with name: %s' % (self.request.url, name) 19 return Response( 20 content_type='text/plain', 21 body=body 22 )
Update the tests in
request_response/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 inst = TutorialViews(request) 18 response = inst.home() 19 self.assertEqual(response.status, '302 Found') 20 21 def test_plain_without_name(self): 22 from .views import TutorialViews 23 24 request = testing.DummyRequest() 25 inst = TutorialViews(request) 26 response = inst.plain() 27 self.assertIn(b'No Name Provided', response.body) 28 29 def test_plain_with_name(self): 30 from .views import TutorialViews 31 32 request = testing.DummyRequest() 33 request.GET['name'] = 'Jane Doe' 34 inst = TutorialViews(request) 35 response = inst.plain() 36 self.assertIn(b'Jane Doe', response.body) 37 38 39class TutorialFunctionalTests(unittest.TestCase): 40 def setUp(self): 41 from tutorial import main 42 43 app = main({}) 44 from webtest import TestApp 45 46 self.testapp = TestApp(app) 47 48 def test_plain_without_name(self): 49 res = self.testapp.get('/plain', status=200) 50 self.assertIn(b'No Name Provided', res.body) 51 52 def test_plain_with_name(self): 53 res = self.testapp.get('/plain?name=Jane%20Doe', status=200) 54 self.assertIn(b'Jane Doe', res.body)
现在运行测试:
$VENV/bin/pytest tutorial/tests.py -q ..... 5 passed in 0.30 seconds
运行 Pyramid 应用程序时使用:
$VENV/bin/pserve development.ini --reload
在浏览器中打开http://localhost:6543/。您将被重定向到http://localhost:6543/plain。
打开http://localhost:6543/plain?name=Alice在您的浏览器中。
分析¶
在这个视图类中,我们有两个路由和两个视图,第一个通过HTTP重定向指向第二个。Pyramid形罐头 generate redirects 从视图中返回特殊对象或引发特殊异常。
在这个Pyramid视图中,我们从 request.url
. 另外,如果您访问了http://localhost:6543/plain?name=alice,名称包含在响应正文中:
URL http://localhost:6543/plain?name=alice with name: alice
最后,我们设置响应的内容类型和主体,然后返回响应。
我们更新了单元测试和功能测试,以证明我们的代码执行重定向,但也处理发送和不发送 /plain?name
.
额外credit¶
我们也可以
raise HTTPFound(location='/plain')
而不是退回?如果是,有什么区别?