14:Ajax开发与JSON渲染器¶
现代Web应用程序不仅仅是呈现的HTML。动态页面现在使用JavaScript通过请求服务器数据作为JSON来更新浏览器中的UI。Pyramid用 JSON渲染器 .
背景¶
正如我们看到的 08:使用模板生成HTML ,视图声明可以指定呈现器。然后通过渲染器运行视图的输出,渲染器生成并返回响应。我们首先使用变色龙渲染器,然后使用Jinja2渲染器。
然而,渲染器并不局限于生成HTML的模板。Pyramid提供了一个JSON渲染器,它获取python数据,将其序列化为JSON,并执行一些其他功能,如设置内容类型。事实上,您可以编写自己的渲染器(或扩展内置渲染器),其中包含用于唯一应用程序的自定义逻辑。
步骤¶
首先我们复制
view_classes
步骤:cd ..; cp -r view_classes json; cd json $VENV/bin/pip install -e .
我们为添加了一条新路线
hello_json
在里面json/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', '/') 8 config.add_route('hello', '/howdy') 9 config.add_route('hello_json', '/howdy.json') 10 config.scan('.views') 11 return config.make_wsgi_app()
与其实现一个新视图,我们将在
hello
视图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 return {'name': 'Home View'} 15 16 @view_config(route_name='hello') 17 @view_config(route_name='hello_json', renderer='json') 18 def hello(self): 19 return {'name': 'Hello View'}
我们在年底需要一个新的功能测试
json/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('Home View', response['name']) 20 21 def test_hello(self): 22 from .views import TutorialViews 23 24 request = testing.DummyRequest() 25 inst = TutorialViews(request) 26 response = inst.hello() 27 self.assertEqual('Hello View', response['name']) 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'<h1>Hi Home View', res.body) 41 42 def test_hello(self): 43 res = self.testapp.get('/howdy', status=200) 44 self.assertIn(b'<h1>Hi Hello View', res.body) 45 46 def test_hello_json(self): 47 res = self.testapp.get('/howdy.json', status=200) 48 self.assertIn(b'{"name": "Hello View"}', res.body) 49 self.assertEqual(res.content_type, 'application/json') 50
运行测试:
$VENV/bin/pytest tutorial/tests.py -q ..... 5 passed in 0.47 seconds
运行 Pyramid 应用程序时使用:
$VENV/bin/pserve development.ini --reload
在浏览器中打开http://localhost:6543/howdy.json,您将看到结果的json响应。
分析¶
之前,我们更改了视图函数和方法以返回Python数据。这种对面向数据的视图层的更改使测试编写更加容易,从而将模板化与视图逻辑分离开来。
由于Pyramid有一个JSON渲染器和模板化渲染器,返回JSON是一个简单的步骤。在这种情况下,我们保持完全相同的视图,并安排返回视图数据的JSON编码。我们这样做是:
向地图添加路线
/howdy.json
到路由名称。提供一个
@view_config
将该路由名称与现有视图关联的。压倒一切 视图配置中提到
hello_json
路由,这样当路由匹配时,我们使用JSON呈现器而不是home.pt
否则将使用的模板呈现器。
事实上,对于纯Ajax风格的Web应用程序,我们可以通过使用Pyramid的视图谓词来匹配 Accepts:
由现代Ajax实现发送的头。
Pyramid的JSON渲染器使用基本的python JSON编码器,从而继承了它的优点和缺点。例如,python不能本机对datetime对象进行JSON编码。在Pyramid中有许多解决方案,包括使用自定义渲染器扩展JSON渲染器。
参见
正在写入使用渲染器的视图可调用文件, JSON渲染器, and 添加和更改渲染器