09:使用视图类组织视图

将视图函数更改为视图类的方法,然后将一些声明移动到类级别。

背景

到目前为止,我们的观点是简单的、独立的功能。很多时候你的观点是相互关联的。它们可以由不同的方式来查看或处理同一数据,也可以是处理多个操作的RESTAPI。将这些视图分组为 view class 有道理:

  • 组视图。

  • 集中一些重复的默认值。

  • 分享一些州和帮手。

在这一步中,我们只做了绝对最小值来将现有视图转换为视图类。在后面的教程步骤中,我们将深入研究视图类。

目标

  • 将相关视图分组到视图类中。

  • 使用类级别集中配置 @view_defaults .

步骤

  1. 首先,我们复制上一步的结果:

    cd ..; cp -r templating view_classes; cd view_classes
    $VENV/bin/pip install -e .
    
  2. 我们的 view_classes/tutorial/views.py 现在有了一个包含两个视图的视图类:

     1from pyramid.view import (
     2    view_config,
     3    view_defaults
     4    )
     5
     6@view_defaults(renderer='home.pt')
     7class TutorialViews:
     8    def __init__(self, request):
     9        self.request = request
    10
    11    @view_config(route_name='home')
    12    def home(self):
    13        return {'name': 'Home View'}
    14
    15    @view_config(route_name='hello')
    16    def hello(self):
    17        return {'name': 'Hello View'}
    
  3. 我们的单元测试 view_classes/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)
    
  4. 现在运行测试:

    $VENV/bin/pytest tutorial/tests.py -q
    ....
    4 passed in 0.34 seconds
    
  5. 运行 Pyramid 应用程序时使用:

    $VENV/bin/pserve development.ini --reload
    
  6. 在浏览器中打开http://localhost:6543/和http://localhost:6543/howdy。

分析

为了简化到视图类的转换,我们没有引入任何新功能。我们只是将视图函数更改为视图类上的方法,然后更新测试。

在我们 TutorialViews 视图类,您可以看到我们的两个视图函数在逻辑上作为一个公共类上的方法分组在一起。因为这两个视图共享同一个模板,我们可以将其移动到 @view_defaults 类级别的装饰器。

测试需要改变。显然,我们需要导入视图类。但是,您也可以在测试中看到模式,首先用虚拟请求实例化视图类,然后调用正在测试的视图方法。