前面介绍了几个基本的flask程序结构的模块,下面回顾下所有模块的功能:
1. config.py:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
FLASKY_MAIL_SUBJECT_PREFIX='[Flasky]'
FLASKY_MAIL_SENDER = '879651072@qq.com'
FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')
SQLALCHEMY_TRACK_MODIFICATIONS = True
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEBUG = True
MAIL_SERVER = 'smtp.qq.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URI') or \
'sqlite:///' + os.path.join(basedir,'data-dev.sqlite')
class TestingConfig(Config):
TESTING = False
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URI') or \
'sqlite:///' + os.path.join(basedir,'data-test.sqlite')
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI') or \
'sqlite:///' + os.path.join(basedir,'data.sqlite')
config={
'development':DevelopmentConfig,
'testing':TestingConfig,
'production':ProductionConfig,
'default':DevelopmentConfig
}
config.py主要提供flask的程序实例app的配置,通过app.config.from_object()的app接口对Config类对象进行加载,来进行app的配置
2. app/main/errors.py
from flask import render_template
from . import main
@main.app_errorhandler(404)
def page_not_found(e):
return render_template('404.html'),404
@main.app_errorhandler(500)
def inter_server_error(e):
return render_template('500.html'),500
定义错误界面的模块,main为一个蓝本对象,通过main.app_errorhandler将url和视图函数进行关联。
3. app/main/views.py
from datetime import datetime
from flask import render_template,session,redirect,url_for,current_app
from . import main
from .forms import NameForm
from .. import db
from ..models import User
from .. import mail
from ..email import msg
@main.route('/',methods=['GET','POST'])
def index():
name=None
form=NameForm()
if form.validate_on_submit():
user=User.query.filter_by(username=form.name.data).first()
if user is None:
user =User(username=form.name.data)
db.session.add(user)
session['konwn'] = False
if current_app.config['FLASKY_ADMIN']:
mail.send(msg)
else:
session['known'] = True
session['name']= form.name.data
form.name.data=''
return redirect(url_for('main.index'))
return render_template('index.html',form=form,name=session.get('name'),
known=session.get('known',False))
视图函数模块,主要通过main.route()添加url和普通视图函数的映射。
4. app/main/forms.py
from flask_wtf import FlaskForm
from wtforms import TextField,SubmitField
from wtforms.validators import DataRequired
class NameForm(FlaskForm):
name=TextField('what is your name?',validators=[DataRequired()])
submit=SubmitField('Submit')
封装了表单类的模块,在视图模块中调用
5.app/main/__int__.py
from flask import Blueprint
main=Blueprint('main',__name__)
from . import views,errors
包初始化模块,定义了一个蓝本对象main,以在views.py和errors.py中使用
6. app/models.py
from app import db
class Role(db.Model):
__tablename__='role'
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(64),unique=True)
users=db.relationship('User',backref='role',lazy='dynamic')
def __repr__(self):
return '<Role %r>'% self.name
class User(db.Model):
__tablename__='users'
id=db.Column(db.Integer,primary_key=True)
username=db.Column(db.String(64),unique=True,index=True)
role_id=db.Column(db.Integer,db.ForeignKey('role.id'))
def __repr__(self):
return '<User %r>'% self.username
定义的数据库模块,封装了数据库模型。
7. app/email.py
from flask_mail import Message
class MyMessage(Message):
def __init__(self,subject,sender,recipients):
super(MyMessage,self).__init__(subject,sender=sender,recipients=recipients)
body='text body'
msg=MyMessage('mysubject','879651072@qq.com',['879651072@qq.com'])
msg.body='text body'
msg.html='<b>HTML</b> body'
邮件模块,封装了电子邮件的类对象,mail.send()可进行发送
8. app/__init__.py
from flask import Flask,render_template
from flask_bootstrap import Bootstrap
from flask_mail import Mail
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
from config import config
bootstrap=Bootstrap()
mail=Mail()
moment=Moment()
db=SQLAlchemy()
def create_app(config_name):
app=Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
mail.init_app(app)
moment.init_app(app)
db.init_app(app)
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
app包的初始化模块,定义了工厂函数create_app(),可以通过配置语句创建开发/测试/生产不同配置的flask程序对象。
9. app/templates
存放程序html模板文件的目录
10. app/static
存放静态文件的目录
11. migrations
存放了数据库的迁移脚本的目录
12. test/test_basic.py
import unittest
from flask import current_app
from app import create_app,db
class BasicTestCase(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_exits(self):
self.assertFalse(current_app is None)
def test_app_is_testing(self):
self.assertFalse(current_app.config['TESTING'])
单元测试模块,定义了单元测试用例。
13. requirements.txt
alembic==0.8.8
blinker==1.4
click==6.6
dominate==2.2.1
Flask==0.11.1
Flask-Bootstrap==3.3.7.0
Flask-Mail==0.9.1
Flask-Migrate==2.0.0
Flask-Moment==0.5.1
Flask-Script==2.0.5
Flask-SQLAlchemy==2.1
Flask-WTF==0.13.1
itsdangerous==0.24
Jinja2==2.8
Mako==1.0.4
MarkupSafe==0.23
python-editor==1.0.1
SQLAlchemy==1.1.2
visitor==0.1.3
Werkzeug==0.11.11
WTForms==2.1
需求模块,通过pip freeze > requirement.txt生成,记录了程序中各个模块的版本信息。
14. manager.py
#!/usr/bin/env python
import os
from app import create_app,db
from app.models import User,Role
from flask_script import Manager,Shell
from flask_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)
@manager.command
def test():
"""Run the unit tests"""
import unittest
tests=unittest.TestLoader().discover('test')
unittest.TextTestRunner(verbosity=2).run(tests)
@manager.command
def myprint():
print 'hello world'
if __name__=='__main__':
manager.run()
程序管理模块,定义程序的运行环境和命令。
Github位置:
https://github.com/HymanLiuTS/flaskTs
克隆本项目:
git clone git@github.com:HymanLiuTS/flaskTs.git
获取本文源代码:
git checkout FL29