3.1. 建立 Web 应用框架

3.1.1. 理解控制器
3.1.2. 修改控制器映射
3.1.3. 加入模组和单元测试

我们的应用定名为 pySvnManager。建立同名的 Pylons 框架:

$ paster create -t pylons pySvnManager
Selected and implied templates:
Pylons#pylons  Pylons application template

Variables:
egg:      pySvnManager
package:  pysvnmanager
project:  pySvnManager
Enter template_engine (mako/genshi/jinja/etc: Template language) ['mako']:
Enter sqlalchemy (True/False: Include SQLAlchemy 0.4 configuration) [False]:
Creating template pylons
Creating directory ./pySvnManager
…
$ cd pySvnManager
$ ls -F
development.ini  ez_setup.py  pysvnmanager/           README.txt  setup.py
docs/            MANIFEST.in  pySvnManager.egg-info/  setup.cfg   test.ini

启动Web应用:

$ paster serve --reload development.ini
Starting subprocess with file monitor
Starting server in PID 817.
serving on http://127.0.0.1:5000

用浏览器访问 http://127.0.0.1:5000 会看到一个网页。这个网页实际上调用的是 public/index.html 文件。如果删除该文件,则浏览器显示 404错误(网页未找到)。

3.1.1. 理解控制器

下面用命令创建控制器 check,会产生两个文件,一个是控制器文件本身: controllers/check.py,另外一个是单元测试文件: tests/functional/test_check.py

$ paster controller check
Creating /home/jiangxin/pyenv/pySvnManager/pysvnmanager/controllers/check.py
Creating /home/jiangxin/pyenv/pySvnManager/pysvnmanager/tests/functional/test_check.py

用浏览器访问URL:http://127.0.0.1:5000/check/ 会看到Hello World。 我们追根溯源,会看到 controllers/check.py 中的代码:

class CheckController(BaseController):

    def index(self):
        return 'Hello World'

哦,原来如此。Pylons 已经将 URL到代码的映射搞定!就是将浏览器对 URL 的访问映射到控制器代码,再由控制器处理后将结果显示给浏览器。 控制器调用实现逻辑(即Model),然后把从Model获取的结果填充到模板(View)中, 于是 MVC 便实现了逻辑和展现分离。Pylons 框架实现的将URL映射到控制器代码, 和 Windows 下 VC/Delphi 等GUI编程中将事件(鼠标、按钮等)映射到对应的代码是多么的近似。

3.1.2. 修改控制器映射

还记得我们已经删除了 public/index.html 文件么? 我们现在通过修改控制器映射,将 Web 应用的缺省首页指向我们新建立的 controller。 要修改的文件就是: config/routing.py

18     map.connect('/error/{action}', controller='error')
19     map.connect('/error/{action}/{id}', controller='error')
20
21     # CUSTOM ROUTES HERE
22     map.connect('/', controller='check', action='index')
23
24     map.connect('/{controller}')
25     map.connect('/{controller}/{action}')
26     map.connect('/{controller}/{action}/{id}')

第22行是我们新增的,告诉Pylons,将缺省的主页定位到名为 check 的控制器的 index 方法(动作)。

我们打开浏览器访问 http://127.0.0.1:5000/ 会自动定位到 http://127.0.0.1:5000/check/index

3.1.3. 加入模组和单元测试

把我们已经开发完毕的 svnauthz 模组及其单元测试放到 pySvnManager 的代码树中,因为 svnauthzpySvnManager 的耦合很紧,没有必要单独维护 svnauthz 模组。

pySvnManager/model 目录是放置模组的地方, 将 svnauthz 的模组放在该目录下。

至于单元测试用例,则应该拷贝到 pysvnmanager/tests 目录下。该目录下有文件 test_models.py,就是用于测试模组的。 我们可以用 test_svnauthz.py 覆盖 空文件 test_models.py ,并在该文件中设置 Python 包含路径, 以便能成功包含要测试的模组:

1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
… 
20 import os
21 import sys
22 sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
23
24 from pysvnmanager.tests import *
25 from pysvnmanager import model
26 from pysvnmanager.model.svnauthz import *

实验一下 nosetests 是否依然可靠运行。

$ nosetests
.............
----------------------------------------------------------------------
Ran 13 tests in 0.546s

OK