pip freeze >requirement.txt 自动生成版本号

pip install -r requirement.txt 自动下载对应的库

梳理结构

config.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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= 'Flasky Admin <flasky@example.com>' # 发件人
FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN') # 收件人 @staticmethod
def init_app(app):
pass class DevelopmentConfig(Config):
DEBUG=True
# 邮件配置
MAIL_SERVER= 'smtp.qq.com'
MAIL_PORT = 465
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_URL') or 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite') class TestingConfig(Config):
TESTING=True
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or 'sqlite:///' + os.path.join(basedir,'data-test.sqlite') class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///' + os.path.join(basedir,'data.sqlite') config={
'development':DevelopmentConfig,
'testing':TestingConfig,
'production':ProductionConfig,
'default':DevelopmentConfig
}

app/__init__.py   使用程序工厂函数

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask
from flask_moment import Moment
from flask_bootstrap import Bootstrap
from flask_mail import Mail
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 . import main as main_blueprint
app.register_blueprint(main_blueprint)
return app

蓝本中实现路由和自定义错误页面

创建蓝本 app/main/__init__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Blueprint
main = Blueprint('main',__name__)
from . import views,errors

注册蓝本 app/__init__.py

# 附加使用蓝本路由和错误页面
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)

app/main/error.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import render_template
from . import main #主程序的errorhandler
@main.errorhandler(404)
def page_not_find(e):
return render_template('404.html'), 404 @main.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500

main/views.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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 ..email import send_mail # 使用蓝本自定义路由
@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['known']=False
if current_app.config['FLASKY_ADMIN']:
send_mail(current_app.config['FLASKY_ADMIN'],'New user','mail/new_user',user=user)
else:
session['known'] = True
session['name']=form.name.data
form.name.data=''
return redirect(url_for('.index'))# 蓝本中index函数在main.index下
return render_template('index.html', name=session.get('name'), form=form, known=session.get('known',False))

main/forms.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired class NameForm(FlaskForm):
name = StringField('姓名', validators=[DataRequired()])
submit = SubmitField('提交')

app/email.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from threading import Thread
from flask import render_template,current_app
from . import mail
from flask_mail import Message
def send_async_email(app,msg):
with app.app_context():
mail.send(msg) def send_mail(to,subject,template,**kwargs):
app = current_app._get_current_object()
msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,sender=app.config['FLASKY_MAIL_SENDER'],recipients=[to])
msg.body=render_template(template + '.txt',**kwargs)
msg.html = render_template(template + '.html', **kwargs)
thr = Thread(target=send_async_email,args=[app,msg])
thr.start()
return thr

app/models.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from app import db
class Role(db.Model):
__tablename__='roles'
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('roles.id')) def __repr__(self):
return '<User %r>' % self.username

manage.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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)
manager.add_command('db',MigrateCommand)
# 集成python shell
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.command
def test():
'''启动单元测试'''
import unittest
tests=unittest.TestLoader().discover('tests')
unittest.TextTestRunner(verbosity=2).run(tests) if __name__ == '__main__':
manager.run()

requirements.txt

alabaster==0.7.9
alembic==0.9.2
anaconda-client==1.6.0
anaconda-navigator==1.5
anaconda-project==0.4.1
astroid==1.4.9
astropy==1.3
attrs==16.3.0
Automat==0.5.0
Babel==2.3.4
backports.shutil-get-terminal-size==1.0.0
beautifulsoup4==4.5.3
bitarray==0.8.1
blaze==0.10.1
blinker==1.4
bokeh==0.12.4
boto==2.45.0
Bottleneck==1.2.0
cffi==1.9.1
chardet==2.3.0
chest==0.2.3
click==6.7
cloudpickle==0.2.2
clyent==1.2.2
colorama==0.3.7
comtypes==1.1.2
conda==4.3.16
configobj==5.0.6
constantly==15.1.0
contextlib2==0.5.4
cryptography==1.7.1
cssselect==1.0.1
cycler==0.10.0
Cython==0.25.2
cytoolz==0.8.2
dask==0.13.0
datashape==0.5.4
decorator==4.0.11
dill==0.2.5
Django==1.11
docutils==0.13.1
dominate==2.3.1
et-xmlfile==1.0.1
fastcache==1.0.2
Flask==0.12
Flask-Bootstrap==3.3.7.1
Flask-Cors==3.0.2
Flask-Mail==0.9.1
Flask-Migrate==2.0.3
Flask-Moment==0.5.1
Flask-Script==2.0.5
Flask-SQLAlchemy==2.2
Flask-WTF==0.14.2
get==0.0.0
gevent==1.2.1
greenlet==0.4.11
h5py==2.6.0
HeapDict==1.0.0
idna==2.2
imagesize==0.7.1
incremental==16.10.1
ipykernel==4.5.2
ipython==5.1.0
ipython-genutils==0.1.0
ipywidgets==5.2.2
isort==4.2.5
itsdangerous==0.24
jdcal==1.3
jedi==0.9.0
jieba==0.38
Jinja2==2.9.4
jsonschema==2.5.1
jupyter==1.0.0
jupyter-client==4.4.0
jupyter-console==5.0.0
jupyter-core==4.2.1
lazy-object-proxy==1.2.2
llvmlite==0.15.0
locket==0.2.0
lxml==3.7.2
Mako==1.0.6
MarkupSafe==0.23
matplotlib==2.0.0
menuinst==1.4.4
mistune==0.7.3
mpmath==0.19
multipledispatch==0.4.9
nbconvert==4.2.0
nbformat==4.2.0
networkx==1.11
nltk==3.2.2
nose==1.3.7
notebook==4.3.1
numba==0.30.1
numexpr==2.6.1
numpy==1.11.3
numpydoc==0.6.0
odo==0.5.0
olefile==0.44
openpyxl==2.4.1
pandas==0.19.2
parsel==1.1.0
partd==0.3.7
path.py==0.0.0
pathlib2==2.2.0
patsy==0.4.1
pep8==1.7.0
pickleshare==0.7.4
Pillow==4.0.0
ply==3.9
post==0.0.0
prompt-toolkit==1.0.9
psutil==5.0.1
public==0.0.0
py==1.4.32
pyasn1==0.1.9
pyasn1-modules==0.0.8
pycosat==0.6.1
pycparser==2.17
pycrypto==2.6.1
pycurl==7.43.0
PyDispatcher==2.0.5
pyflakes==1.5.0
Pygments==2.1.3
pylint==1.6.4
PyMySQL==0.7.11
pyOpenSSL==16.2.0
pyparsing==2.1.4
pytest==3.0.5
python-dateutil==2.6.0
python-editor==1.0.3
pytz==2016.10
pywin32==220
PyYAML==3.12
pyzmq==16.0.2
QtAwesome==0.4.3
qtconsole==4.2.1
QtPy==1.2.1
query-string==0.0.0
queuelib==1.4.2
request==0.0.0
requests==2.12.4
rope-py3k==0.9.4.post1
scikit-image==0.12.3
scikit-learn==0.18.1
scipy==0.18.1
Scrapy==1.3.3
seaborn==0.7.1
service-identity==16.0.0
setupfiles==0.0.0
simplegeneric==0.8.1
singledispatch==3.4.0.3
six==1.10.0
snowballstemmer==1.2.1
sockjs-tornado==1.0.3
sphinx==1.5.1
spyder==3.1.2
SQLAlchemy==1.1.5
statsmodels==0.6.1
sympy==1.0
tables==3.2.2
toolz==0.8.2
tornado==4.4.2
traitlets==4.3.1
Twisted==17.1.0
unicodecsv==0.14.1
visitor==0.1.3
w3lib==1.17.0
wcwidth==0.1.7
Werkzeug==0.11.15
widgetsnbextension==1.2.6
win-unicode-console==0.5
wordcloud==1.3.1
wrapt==1.10.8
WTForms==2.1
xlrd==1.0.0
XlsxWriter==0.9.6
xlwings==0.10.2
xlwt==1.2.0
zope.interface==4.3.3

单元测试

test/test_basic.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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_exists(self):
self.assertFalse(current_app is None)
def test_app_is_testing(self):
self.assertTrue(current_app.config['TESTING'])

单元测试注册到主程序manager.py

@manager.command
def test():
'''启动单元测试'''
import unittest
tests=unittest.TestLoader().discover('tests')
unittest.TextTestRunner(verbosity=2).run(tests)

1、创建数据库

python manage.py shell

from app import db

db.create_all()

2、创建数据库迁移

python hello.py db init # 创建 migrations 文件夹,所有迁移脚本都存放其中

3、创建迁移脚本

python manage.py db migrate

4、更新数据库

python manage.py db upgrade

Flask 学习 六 大型程序结构的更多相关文章

  1. Celery 与 Flask 大型程序结构的结合

    :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...

  2. Python学习笔记(Ⅰ)——Python程序结构与基础语法

    作为微软的粉丝,最后终于向Python低头了,拖了两三个月终于下定决心学习Python了.不过由于之前受到C/C#等语言影响的思维定式,前期有些东西理解起来还是很费了些功夫的. 零.先抄书: 1.Py ...

  3. flask学习(六):URL传参

    1. 参数的作用:可以在相同的URL,但是指定不同的参数,来加载不同的数据 例如:简书上每一篇文章前面的URL相同,只是后面的参数不同 2. 在flask中如何使用参数: 注意: 1) 参数需要放在两 ...

  4. [ Python ] Flask 基于 Web开发 大型程序的结构实例解析

    作为一个编程入门新手,Flask是我接触到的第一个Web框架.想要深入学习,就从<FlaskWeb开发:基于Python的Web应用开发实战>这本书入手,本书由于是翻译过来的中文版,理解起 ...

  5. c# 程序结构

    最近工作中需要用到c#,所以从今天开始博客不定期更新c#学习笔记 c#程序结构大体分为, 命名空间 类 Main 方法   命名空间 相当于一个仓库 通过 using 引入命名空间 比如 using ...

  6. Flask从入门到精通之大型程序的结构一

    尽管在单一脚本中编写小型Web 程序很方便,但这种方法并不能广泛使用.程序变复杂后,使用单个大型源码文件会导致很多问题.不同于大多数其他的Web 框架,Flask 并不强制要求大型项目使用特定的组织方 ...

  7. C++ Primer 学习笔记_88_用于大型程序的工具 --异常处理[续1]

    用于大型程序的工具 --异常处理[续1] 四.又一次抛出 有可能单个catch不能全然处理一个异常.在进行了一些校正行动之后,catch可能确定该异常必须由函数调用链中更上层的函数来处理,catch能 ...

  8. 【Intel AF 2.1 学习笔记一】AF程序结构

    Intel App Framework(原jqMobi)是用来开发hybrid app的开源免费框架,被intel收编之后发布了最新的2.1版本,最近正在学习.af的所谓程序结构,就是AF网页的架构, ...

  9. 毕业设计预习:VHDL入门知识学习(一) VHDL程序基本结构

    VHDL入门知识学习(一) VHDL程序基本结构 简介 VHDL程序基本结构 简介 概念: HDL-Hardware Description Language-硬件描述语言-描述硬件电路的功能.信号连 ...

随机推荐

  1. jquery的过滤学习

    $("p").eq(1)  匹配下标为1的p标签        $("p").hasClass("a")匹配所有p标签class中包含a的 ...

  2. 【BZOJ3160】万径人踪灭(FFT,Manacher)

    [BZOJ3160]万径人踪灭(FFT,Manacher) 题面 BZOJ 题解 很容易想到就是满足条件的子序列个数减去回文子串的个数吧... 至于满足条件的子序列 我们可以依次枚举对称轴 如果知道关 ...

  3. 【noip模拟】Fantasia

    Time Litmit: 1000ms      Memory Limit: 256MB Description 给定一张 $N$ 个点.$M$ 条边的无向图 $G$ .每个点有个权值$W_i$. 我 ...

  4. 解决将龙邱oled库移植到野火工程里,oled汉字无法显示问题

    第一,检查oled是否和单片机控制引脚正确相连. GND VCC CLK:时钟信号 miso RST: DC:DATE COMMAND/CONTROL CS:CHIP SELECT 第二,检查工程里是 ...

  5. php 后端跨域请求

    header("Access-Control-Allow-Origin: http://a.com"); // 允许a.com发起的跨域请求 //如果需要设置允许所有域名发起的跨域 ...

  6. C语言与C++语言之间关系

    很多时候我们对于C和C++的区别不是很清楚,以至于弄混的情况并不少见.那C语言和C++语言到底是怎么回事呢? 首先,我们来看下百度百科对语言和C++语言描述,相对而说也还算是比较权威的. C语言 C语 ...

  7. JavaScript编码规范(2)

    变量 [强制] 变量.函数在使用前必须先定义. // good var name = 'MyName'; // bad name = 'MyName'; [强制] 每个 var 只能声明一个变量. 解 ...

  8. DB2开发系列之一——基本语法

    最近看了些db2开发方面的资料,现做摘要,以供自己和大家参考: 1.变量声明 DECLARE v_salary DEC(9,2) DEFAULT 0.0; DECLARE v_status char( ...

  9. Java IO流简介

    Java中的流是什么? java中的流是一个抽象的概念,在java的程序中需要把文件从一个设备传输到另一个设备上,这个设备可以是内存,程序,文件,网络.把在这些之间传输的叫做流.官方的解释:流是一组有 ...

  10. MongoDB系列二(介绍).

    一.特点 学习一个东西,至少首先得知道它能做什么?适合做什么?有什么优缺点吧? 传统关系型数据库,遵循三大范式.即原子性.唯一性.每列与主键直接关联性.但是后来人们慢慢发现,不要把这些数据分散到多个表 ...