Flask Web Development —— 大型应用程序结构(下)

四、启动脚本

顶层目录中的manage.py文件用于启动应用。这个脚本会在示例7-8中展现。html

示例7-8. manage.py:启动脚本python

#!/usr/bin/env python
import os
from app import create_app, db
from app.models import User, Role
from flask.ext.script import Manager, Shell
from flask.ext.migrate import Migrate, MigrateCommand

app = create_app(os.getenv('FLASK_CONFIG') or 'default') 
manager = Manager(app)
migrate = Migrate(app, db)

def make_shell_context():
    return dict(app=app, db=db, User=User, Role=Role)

manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)

if __name__ == '__main__': 
    manager.run()

这个脚本开始于建立应用程序。使用环境变量FLASK_CONFIG,若它已经定义了则从中获取配置;若是没有,则是用默认配置。而后用于Python shell的Flask-Script、Flask-Migrate以及自定义上下文会被初始化。git

为了方便,会增长一行执行环境,这样在基于Unix的操做系统上能够经过./manage.py来执行脚原本替代冗长的python manage.pysql

五、需求文件

应用程序必须包含requirements.txt文件来记录全部依赖包,包括精确的版本号。这很重要,由于能够在不一样的机器上从新生成虚拟环境,例如在生产环境的机器上部署应用程序。这个文件能够经过下面的pip命令自动生成:shell

(venv) $ pip freeze >requirements.txt

当安装或更新一个包以后最好再更新一下这个文件。如下展现了一个需求文件示例:数据库

Flask==0.10.1
Flask-Bootstrap==3.0.3.1
Flask-Mail==0.9.0
Flask-Migrate==1.1.0
Flask-Moment==0.2.0
Flask-SQLAlchemy==1.0
Flask-Script==0.6.6
Flask-WTF==0.9.4
Jinja2==2.7.1
Mako==0.9.1
MarkupSafe==0.18
SQLAlchemy==0.8.4
WTForms==1.0.5
Werkzeug==0.9.4
alembic==0.6.2
blinker==1.3
itsdangerous==0.23

当你须要完美复制一个虚拟环境的时候,你能够运行如下命令建立一个新的虚拟环境:flask

(venv) $ pip install -r requirements.txt

当你读到这时,示例requirements.txt文件中的版本号可能已通过时了。若是喜欢你能够尝试用最近发布的包。若是遇到任何问题,你能够随时回退到需求文件中与应用兼容的指定版本。session

六、单元测试

这个应用很是小以致于不须要太多的测试,可是做为示例会在示例7-9中展现两个简单的测试定义。app

示例7-9. tests/test_basics.py:单元测试函数

import unittest
from flask import current_app 
from app import create_app, db

class BasicsTestCase(unittest.TestCase): 
    def setUp(self):
        self.app = create_app('testing')
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()

    def tearDown(self): 
        db.session.remove() 
        db.drop_all() 
        self.app_context.pop()

    def test_app_exists(self): 
        self.assertFalse(current_app is None)

    def test_app_is_testing(self): 
        self.assertTrue(current_app.config['TESTING'])

编写好的测试使用的是来自于Python标准库中标准的unittest包。setUp()tearDown()方法在每一个测试以前和以后运行,且任何一个方法必须以test_开头做为测试来执行。

建议:若是你想要学习更多使用Python的unittest包来写单元测试的内容,请参阅官方文档

setUp()方法尝试建立一个测试环境,相似于运行应用程序。首先它建立应用程序配置用于测试并激活上下文。这一步确保测试能够和常规请求同样访问current_app。而后,当须要的时候,能够建立一个供测试使用的全新数据库。数据库和应用程序上下文会在tearDown()方法中被移除。

第一个测试确保应用程序实例存在。第二个测试确保应用程序在测试配置下运行。为了确保tests目录有效,须要在tests目录下增长__init__.py文件,不过该文件能够为空,这样unittest包能够扫描全部模块并定位测试。

建议:若是你有克隆在GitHub上的应用程序,你如今能够运行git checkout 7a来切换到这个版本的应用程序。为了确保你已经安装了全部依赖集,须要运行pip install -r requirements.txt

为了运行单元测试,能够在manage.py脚本中增长一个自定义的命令。

示例7-10展现如何添加测试命令。

示例7-10. manage.pyt:单元测试启动脚本

@manager.command
def test():
    """Run the unit tests."""
    import unittest
    tests = unittest.TestLoader().discover('tests') 
    unittest.TextTestRunner(verbosity=2).run(tests)

manager.command装饰器使得它能够很容易的实现自定义命令。被装饰的函数名能够被当作命令名使用,且函数的文档字符串会显示帮助信息。test()函数的执行会调用unittest包中的测试运行器。

单元测试能够像下面这样执行:

(venv) $ python manage.py test
test_app_exists (test_basics.BasicsTestCase) ... ok
test_app_is_testing (test_basics.BasicsTestCase) ... ok

.----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

七、数据库启动

与单脚本的应用相比,重构后的应用使用不一样数据库。

从环境变量中获取的数据库URL做为首选,默认SQLite数据库做为可选。三个配置中的环境变量和SQLite数据库文件名是不同的。例如,开发配置的URL是从DEV_DATABASE_URL环境变量中获取,若是没有定义则会使用名为data-dev.sqlite的SQLite数据库。

不管数据库URL源的是哪个,都必须为新的数据库建立数据库表。若是使用了Flask-Migrate来保持迁移跟踪,数据库表能够被建立或更新到最近的版本经过下面的命令:

(venv) $ python manage.py db upgrade

相信与否,已经到了第一部分结束的地方。你如今已经学到了Flask必要的基本要素,可是你不肯定如何将这些零散的知识组合在一块儿造成一个真正的应用程序。第二部分的目的是经过开发一个完整的应用程序来带领你继续前行。

注:前段时间才知道这本书已经由图灵社区出版翻译,已经开始预售了,并于12月19日到货。喜欢的朋友也能够[点我]购买一本。后面的章节就再也不继续更新了,本身确定也会去支持这本书的。

相关文章
相关标签/搜索