7.1 项目结构

该结构是根据<<FlaskWeb开发:基于Python的Web应用开发实战>> 第7章中推荐的项目结构搭建,是一种使用包和模块组织大型程序的方式。

这种结构有4个顶级的文件夹:

  • Flask 主程序(功能业务代码)一般都保存在app包中;
  • migrations 文件夹包含数据库迁移脚本;
  • 单元测试编写在test包中
  • venv文件夹包含Python虚拟环境

同时还创建了一些新文件:

  • requirements.txt 列出了所有的依赖包,便于在其他业务环境中生成相同的虚拟环境;
  • config.py 由于存储配置
  • manage.py 用于启动程序及其他的程序任务(本例中加入了Shell,MigrateCommand)

7.2 配置选项

我们给程序设定了多个配置,开发,测试,生产环境。

config.py

 1 import os
 2
 3 basedir = os.path.abspath(os.path.dirname(__file__))
 4
 5
 6 class Config:
 7     SECRET_KEY = os.environ.get('SECRET_KEY') or 'Hard to guess string!'
 8     SQLALCHEMY_COMMIT_ON_TEARDOWN = True
 9     SQLALCHEMY_TRACK_MODIFICATIONS = True
10     FLASKY_MAIL_SUBJECT_PREFIX = '[Flasky]'
11     FLASKY_MAIL_SENDER = 'zhangjin@9158.com'
12     FLASK_ADMIN = os.environ.get('FLASKY_ADMIN')
13
14     @staticmethod
15     def init_app(app):
16         pass
17
18
19 class DevelopmentConfig(Config):
20     DEBUG = True
21     MAIL_SERVER = 'mail.9158.com'
22     MAIL_PORT = 587
23     MAIL_USE_TLS = True
24     MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
25     MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
26     SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URI') or 'sqlite:///' + os.path.join(basedir,
27                                                                                                 'data-dev.sqlite')
28
29
30 class TestingConfig(Config):
31     TESTING = True
32     SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URI') or 'sqlite:///' + os.path.join(basedir,
33                                                                                                  'data-test.sqlite')
34
35
36 class ProductionConfig(Config):
37     SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI') or 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
38
39
40 config = {
41     'development': DevelopmentConfig,
42     'testing': TestingConfig,
43     'production': ProductionConfig,
44     'default': DevelopmentConfig
45 }

基类Config包含通用配置,子类分别定义专用的配置。

在3个子类中,SQLALCHEMY_DATABASE_URI变量都被指定了不同的值,这样程序就可以在不同的配置中运行,每个环境都使用指定不同的数据库。

在配置最后,config字典还注册了不同的环境。

7.3 程序包

程序包用来保存所有的代码,模板和静态文件。我们可以把这个包直接成为app,如果有需求也可以使用专有的名字;templates,static,models.py,mail.py都是这个包的一部分。

7.3.1 使用程序工厂函数

app/__init__.py

 1 from flask import Flask, render_template
 2 from flask_bootstrap import Bootstrap
 3 from flask_mail import Mail
 4 from flask_moment import Moment
 5 from flask_sqlalchemy import SQLAlchemy
 6 from config import config
 7
 8 bootstrap = Bootstrap()
 9 mail = Mail()
10 moment = Moment()
11 db = SQLAlchemy()
12
13
14 def create_app(config_name):
15     app = Flask(__name__)
16     app.config.from_object(config[config_name])
17     config[config_name].init_app(app)
18
19     bootstrap.init_app(app)
20     mail.init_app(app)
21     moment.init_app(app)
22     db.init_app(app)
23
24     from .main import main as main_blueprint
25     app.register_blueprint(main_blueprint)
26     return app

构造文件导入了大多数正在使用的Flask扩展,。由于尚未初始化所需的程序实例,所以没有初始化拓展,创建扩展类时没有传入参数。create_app函数就是程序的工厂函数,接收一个参数,是程序使用的配置名。程序的配置在config.py中定义,可直接使用Flask app.config中提供的from_object()方法直接导入程序。

7.3.2 使用蓝本实现程序功能

蓝本和程序类似,也可以定义路由。不同的是,在蓝本中定义的路由处于休眠状态,直到蓝本被注册到程序上面,录有才真正成为程序的一部分。

创建蓝本:

app/main/__init__.py

from flask import Blueprintmain = Blueprint('main', __name__)from . import views, errors

注册蓝本:

app/__init__.py

def create_app(config_name):......from .main import main as main_blueprintapp.register_blueprint(main_blueprint)return app

蓝本中错误处理的程序:

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 internal_server_error(e):return render_template('500.html'), 500

蓝本中定义的程序路由:

app/main/views.py

 1 from datetime import datetime
 2 from flask import render_template, session, redirect, url_for, flash
 3
 4 from . import main
 5 from .forms import NameForm
 6 from .. import db
 7 from ..models import User
 8
 9
10 @main.route('/', methods = ['GET', 'POST'])
11 def index():
12     form = NameForm()
13     if form.validate_on_submit():
14         user = User.query.filter_by(username=form.name.data).first()
15         if user is None:
16             user = User(username=form.name.data)
17             db.session.add(user)
18             session['known'] = False
19         else:
20             session['known'] = True
21         old_name = session.get('name')
22         if old_name is not None and old_name != form.name.data:
23             flash('Look like you have changed your name!')
24         session['name'] = form.name.data
25         form.name.data = ''
26         return redirect(url_for('.index'))
27     all_user = User.query.all()
28     return render_template('index.html', form=form, name=session.get('name'), known=session.get('known', False),
29                            current_time=datetime.utcnow(), user_list=all_user)

在蓝本中编写视图函数主要有两点不同:第一,和前面错误处理程序一样,路由装饰器由蓝本提供;第二url_for函数的用法不同,url_for('.index')。

表单对象也移到了蓝本中

app/main/forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequiredclass NameForm(FlaskForm):name = StringField('What is your name?', validators=[DataRequired()])submit = SubmitField('Submit')

7.4 启动脚本

顶级文件夹中的manage.py用于启动程序。

manage.py

 1 import os
 2 from app import create_app, db
 3 from app.models import User, Role
 4 from flask_script import Manager, Shell
 5 from flask_migrate import Migrate, MigrateCommand
 6
 7 app = create_app(os.getenv('FLASK_CONFIG') or 'default')
 8 manager = Manager(app)
 9 migrate = Migrate(app, db)
10
11
12 def make_shell_context():
13     return dict(app=app, db=db, User=User, Role=Role)
14
15
16 manager.add_command("shell", Shell(make_shell_context))
17 manager.add_command("db", MigrateCommand)
18
19 if __name__ == '__main__':
20     manager.run()

这个脚本先创建程序,如果已经定义了环境变量FLASK_CONFIG,则从变量中读取,否则使用'default'配置。

7.5 需求文件

程序中必须包含一个requirements.txt文件,用于记录程序所依赖的包和包的版本号,pip可以使用如下命令生产这个文件:

(venv) pip freeze > requirements.txt

如果要在新机器上传创建这个一样的虚拟环境,可运行以下命令。

(venv)pip install -r requirements.txt

alembic==0.9.9
blinker==1.4
click==6.7
dominate==2.3.1
Flask==0.12.2
Flask-Bootstrap==3.3.7.1
Flask-Mail==0.9.1
Flask-Migrate==2.1.1
Flask-Moment==0.6.0
Flask-Script==2.0.6
Flask-SQLAlchemy==2.3.2
Flask-WTF==0.14.2
itsdangerous==0.24
Jinja2==2.10
Mako==1.0.7
MarkupSafe==1.0
python-dateutil==2.7.2
python-editor==1.0.3
six==1.11.0
SQLAlchemy==1.2.7
visitor==0.1.3
Werkzeug==0.14.1
WTForms==2.1

转载于:https://www.cnblogs.com/LouisZJ/p/8932392.html

7. Flask 大型程序的结构相关推荐

  1. 西门子1500PLC博途程序实例,大型程序fanuc机器人汽车焊装自动生产线程序,程序硬件结构包括1台西门子1500PLC程序

    西门子1500PLC博途程序实例,大型程序fanuc机器人汽车焊装自动生产线程序,程序硬件结构包括1台西门子1500PLC程序,2台触摸屏TP1500程序 9个智能远程终端ET200SP Profin ...

  2. 西门子1500PLC博途程序实例,大型程序fanuc机器人汽车焊装自动生产线程序,程序硬件结构包括1台西门子1500PLC程序,2台触摸屏TP1500程序

    西门子1500PLC博途程序实例,大型程序fanuc机器人汽车焊装自动生产线程序,程序硬件结构包括1台西门子1500PLC程序,2台触摸屏TP1500程序 9个智能远程终端ET200SP Profin ...

  3. 关于python中程序流程结构-四、python基础(程序目录结构规范)

    程序目录结构: 设计一个层次清晰的目录结构,就是为了达到以下两点: 可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等.从而非常快速 ...

  4. 黑马程序员C语言基础(第五天)运算符与表达式、程序流程结构、数组和字符串、函数

    https://www.bilibili.com/video/BV15W411K7k6?p=93&spm_id_from=pageDriver 黑马程序员C语言基础(第五天)运算符与表达式.程 ...

  5. C++阶段01笔记汇总【C++软件安装、C++初识、数据类型、运算符、程序流程结构、数组、函数、指针、结构体】

    C++| 匠心之作 从0到1入门学编程[视频+课件+笔记+源码] 目录 C++课程安排 1 C++初识 1.1 第一个C++程序 1.1.1 创建项目 1.1.2 创建文件 1.1.3 编写代码 1. ...

  6. [填坑手册]小程序目录结构和组件化使用心得

    小程序目录结构 关于小程序的目录结构,可以说一开始大家都有各自的开发习惯和命名规则,但一旦项目变得复杂庞大的时候,你就发现管理起来和后期维护变得很麻烦,如果是 协同开发 的话,更容易出现 " ...

  7. flask redis_在Flask应用程序中将Redis队列用于异步任务

    flask redis By: Content by Edward Krueger and Josh Farmer, and Douglas Franklin. 作者: 爱德华·克鲁格 ( Edwar ...

  8. ci/cd heroku_在GitLab上设置CI / CD以在Heroku上部署Python Flask应用程序

    ci/cd heroku Recently I came across a challenge to deploy a Python Flask web application to Heroku. ...

  9. 西门子S7-1500PLC大型程序,各种FB块PTO控制20多个轴

    西门子S7-1500PLC大型程序,各种FB块PTO控制20多个轴,5台S7-1200PLC智能IO通讯,ModbusRTU通讯轮询,完整威纶通触摸屏程序,是学习西门子PLC通信.伺服好帮手 程序结构 ...

最新文章

  1. 分类问题中的“维数灾难” - robotMax
  2. **PHP SimpleXML 使用详细例子
  3. 云告警平台 OneAlert :如何帮助运维工程师做好汇报?
  4. Wix安装程序中判断是否安装的.net framwork 4.5
  5. java实现权限_Java实现权限管理的两种方式
  6. 基于无监督深度学习的单目视觉的深度和自身运动轨迹估计的深度神经模型
  7. python自动翻译pdf_python实现从pdf文件中提取文本,并自动翻译的方法
  8. keepalived + LVS实现高可用负载均衡集群
  9. oracle常用查询语句
  10. python画螺旋状图形教程_如何快速绘制一个“螺旋状”图形?
  11. 体温枪PCBA设计生产流程
  12. Nginx配置多个二级域名和多个CA证书
  13. 教你查看预装Win8电脑内置系统激活密钥(Win8 OEM Key)
  14. 通俗易懂去讲解反射(Reflect)
  15. 解决:文件名太长删不掉
  16. health HEALTH_WARN;352 pgs degraded;352 pgs stuck unclean;352 pgs undersized;recovery 20/40 objects
  17. 2022 google chrome 翻译DNS
  18. 仰望银河,深蓝瑶光,极星揽月,武林至尊
  19. Unity在OpenGL模式下Shader编译报错
  20. 干货!使用静态模型分类动态点云序列

热门文章

  1. HDU4026 Unlock the Cell Phone [状态压缩DP]
  2. Oracle IO问题解析(一)
  3. Nginx配置文件的配置说明
  4. JavaScript基础知识(二)
  5. SOAP(Simple Object Access Protocol )简单对象访问协议
  6. linux7 多路径配置,redhat7.3多路径配置
  7. 【Vegas2006】8月24日-花豆擀面做法
  8. 小黄鸭c语言程序代码,新年的小黄鸭 - 题目 - Universal Online Judge
  9. html——inline、block与block-inline区别
  10. htm——position:static、absolute、relative详解