本文主要的目标是创建flask基本的项目架构,总体架构:

详细的项目目录结构:

Flask 项目创建的过程

一.项目(students)创建初始化工作

1. 创建项目的虚拟环境

mkvirtualenv students

2 . 在项目虚拟环境中安装开发中使用的依赖模块

pip install flask==0.12.4
pip install redis
pip install flask-session
pip install flask-script
pip install flask-mysqldb
pip install flask-sqlalchemy
pip install flask-migrate
pip install flask_wtf

3. 创建大致的目录结构

在项目目录下d:/deng/flaskLearn 创建项目文件夹 students,并在该目录下新建一个manage.py 文件

1. manage.py

from flask import Flask

app = Flask(__name__)

@app.route('/index')
def index():
return 'index' if __name__ == '__main__':
app.run()

mange.py终不能存放大量的开发代码, 在开发中应该体现的是一种分工精神,所以我们可以把flask中各种功能代码进行分类分文件存储.

创建项目目录结构:

项目根目录/
├── application/ # 项目主要逻辑代码保存目录
| ├── settings/ # 项目配置存储目录
│ │ ├ dev.py # 开发阶段的配置文件
│ │ ├ prop.py # 生产阶段的配置文件
│ ├── __init__.py # 项目初始化文件
├── manage.py # 项目的终端管理脚本文件

3. 为项目创建mysql数据库

到mysql 数据库中创建项目所用的数据库: students

create database students charset=utf8;

4..配置

settings文件夹中:

  1.settings /__init__.py:

from redis import StrictRedis

class Config(object):

    '''项目配置核心类'''
# 调用模式
DEBUG = True # todo 配置日志
LOG_LEVEL = DEBUG # 设置日志等级 # mysql 数据库的配置信息
# "mysql://用户名:密码@127.0.0.1:3306/连接的数据库名?charset=utf8" # 指定字符集
SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/students?charset=utf8"
# 动态追踪修改设置,如未设置只会提示警告
SQLALCHEMY_TRACK_MODIFICATIONS = False
# 查询时是否显示原始SQL语句
SQLALCHEMY_ECHO = False # 配置redis
REDIS_HOST ='127.0.0.1' # 项目上线以后,这个地址就会被替换成真实ip地址和mysql也是
REDIS_PORT = 6379 #设置密钥 可以通过 base64.b64encode(os.urandom(48))来生成指定一个长度的随机字符串
SECRET_KEY = "ghhBljAa0uzw2afLqJOXrukORE4BlkTY/1vaMuDh6opQ3uwGYtsDUyxcH62Aw3ju"
# flask_session的配置信息
SESSION_TYPE = "redis" # 指定 session 保存到 redis 中
SESSION_USE_SIGNER = True # 让 cookie 中的 session_id 被加密签名处理
SESSION_REDIS = StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=1) # 使用 redis 的实
PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒

  2. settings/dev.py

from . import Config

class DevelopementConfig(Config):

   '''开发模式下的配置'''
# 查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True

  3. settings/prop.py

from . import Config

class ProductionConfig(Config):
'''生产模式下的配置''' DEBUG = False

项目主应用中初始化项目

1.在application/__init__.py文件中,创建flask应用并加载配置:

from flask import Flask
from application.settings.dev import DevelopementConfig
from application.settings.prop import ProductionConfig config = {
"dev": DevelopementConfig,
"prop": ProductionConfig,
} def init_app(config_name):
"""项目的初始化函数"""
app = Flask(__name__) # 设置配置类
Config = config[config_name] # 加载配置
app.config.from_object(Config) return app

2.在manage.py 中调用 init_app 函数,启动项目

from application import init_app

app = init_app("dev")

@app.route("/")
def index():
return "index" if __name__ == '__main__':
app.run()

3.在application/__init__.py项目初始化文件中加载redis或者mysql的初始化代码:

from flask import Flask
from redis import StrictRedis
from flask_wtf.csrf import CSRFProtect
from flask_session import Session from application.settings.dev import DevelopementConfig
from application.settings.prop import ProductionConfig config = {
"dev": DevelopementConfig,
"prop": ProductionConfig,
} # 为了方便redis的连接对象在函数外部可以使用,预先设置一个全局变量,接下来在函数中用于保存redis的连接
redis_store = None def init_app(config_name):
"""项目的初始化功能"""
app = Flask(__name__) # 设置配置类
Config = config[config_name] # 加载配置
app.config.from_object(Config) # redis的链接初始化
global redis_store
redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0) # 开启CSRF防范功能
CSRFProtect(app) # 开启session功能
Session(app) # TODO 注册蓝图对象到app应用中 return app

增加数据库配置

application/__init__.py文件中:

# from flask import Flask
# from redis import StrictRedis
# from flask_wtf.csrf import CSRFProtect
# from flask_session import Session
from flask_sqlalchemy import SQLAlchemy
#
# from application.settings.dev import DevelopementConfig
# from application.settings.prop import ProductionConfig
#
# config = {
# "dev": DevelopementConfig,
# "prop": ProductionConfig,
# }
#
# # 为了方便redis的连接对象在函数外部可以使用,预先设置一个全局变量,接下来在函数中用于保存redis的连接
# redis_store = None
db = SQLAlchemy()
#
# def init_app(config_name):
# """项目的初始化功能"""
# app = Flask(__name__)
#
# # 设置配置类
# Config = config[config_name]
#
# # 加载配置
# app.config.from_object(Config)
#
# # redis的链接初始化
# global redis_store
# redis_store = StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT,db=0)
#
# # 开启CSRF防范功能
# CSRFProtect(app)
#
# # 开启session功能
# Session(app)
#
# 配置数据库链接
db.init_app(app)
#
# # TODO 注册蓝图对象到app应用中
#
# return app

在manage启动文件中新增关于启动过程中的相关功能

在项目根目录下`manage.py中设置项目启动程序并调用__init__.py的app

from application import init_app,db
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand app = init_app("dev") # 使用终端脚本工具启动和管理flask
manager = Manager(app) # 启用数据迁移工具
Migrate(app, db)
# 添加数据迁移的命令到终端脚本工具中
manager.add_command('db', MigrateCommand) @app.route("/")
def index():
return "index" if __name__ == '__main__':
manager.run()

日志

Python 自身提供了一个用于记录日志的标准库模块:logging。

日志的等级

FATAL/CRITICAL = 致命的,危险的     Critical
ERROR = 错误
WARNING = 警告
INFO = 信息
DEBUG = 调试
NOTSET = 没有设置

把日志设置封装成一个函数: 放在application/__init__.py:

from flask import Flask

from application.settings.dev import DevelopementConfig

from application.settings.prop import ProductionConfig

from redis import StrictRedis
from flask_session import Session
from flask_wtf.csrf import CSRFProtect from flask_sqlalchemy import SQLAlchemy # 数据库 import logging
from logging.handlers import RotatingFileHandler config ={
'dev':DevelopementConfig,
'prop':ProductionConfig,
} # 为了方便redis 的连接对象在函数外部可以使用,预先设置一个全局变量,接下来在函数中
# 用于保存redis 的连接
redis_store = None # 增加 数据库配置
db = SQLAlchemy() # SQLAlchemy 类中有一个 init_app方法 # 封装日志函数 # 把 日志相关配置封装成一个日志初始化函数
def setup_log(Config): # 设置 日志的记录等级
logging.basicConfig(level=Config.LOG_LEVEL) # 创建日志记录器 指明日志保存的路径,每个日志文件的最大大小,保存日志文件个数上限
file_log_hander = RotatingFileHandler('logs/log',maxBytes=1024*1024*300,backupCount=10)# 300M # 创建日志记录的格式,日志等级 输入日志信息的文件名 行数,日志信息
formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s') # 为刚创建的日志记录器设置日志记录格式
file_log_hander.setFormatter(formatter) # 为全局的日志工具对象(flaskapps使用的) 添加日志记录器
logging.getLogger().addHandler(file_log_hander) def init_app(config_name):
'''项目初始化函数'''
app = Flask(__name__)
# 设置配置类
Config = config[config_name] # 加载配置
app.config.from_object(Config) # redis 的链接初始化
global redis_store
# db 表示redis 的第几号库
redis_store = StrictRedis(host=Config.REDIS_HOST,port=Config.REDIS_PORT,db=0) # 开启CSRF防范功能
CSRFProtect(app) # 开启session功能 Session(app) # 配置数据库连接
db.init_app(app) # 此处的init_app是 SQLAlchemy 中的一个方法,不是自己写的方法
# todo 启用日志功能
setup_log(Config)
# todo 注册蓝图对象到app应用中 # 用户模块
from .apps.users import users_blu
app.register_blueprint(users_blu) pass return app

在配置文件settings/__init__.py中,设置默认日志等级

class Config(object):
"""项目配置核心类"""
# 调试模式
DEBUG = True # todo 配置日志
LOG_LEVEL = "DEBUG"

新增日志以后的项目目录结构

项目根目录/
├── docs/ # 项目开发相关文档
├── logs/ # 项目运行日志保存目录
| ├── log # 日志文件
├── application/ # 项目主要逻辑代码保存目录
| ├── settings/ # 项目配置存储目录
│   │ ├ dev.py # 开发阶段的配置文件
│   │ ├ prop.py # 生产阶段的配置文件
│   ├── __init__.py # 项目初始化文件
├── manage.py # 项目的终端管理脚本文件

创建蓝图目录

在applications下创建apps目录,apps以后专门用于保存每一个项目的蓝图,

并在apps创建users蓝图(子应用),在users/__init__.py文件中创建蓝图对象

1.users/__init__.py

from flask import Blueprint

users_blu =Blueprint('users_blu',__name__,url_prefix='/users',template_folder='templates',static_folder='static',) # 必须加 /

2.users/views.py

在users蓝图目录中新增对应的视图文件users/views.py,代码:

from . import users_blu

@users_blu.route("/")
def index():
return "首页"

3.在users/__init__.py中引入当前蓝图下所有的视图文件

from flask import Blueprint

users_blu =Blueprint('users_blu',__name__,url_prefix='/users',template_folder='templates',static_folder='static',) # 必须加 /

from .views import *

4. 在项目初始化文件application/__init__.py文件中,注册蓝图对象

application/__init__.py:

# todo 注册蓝图对象到app应用中

    # 用户模块
from .apps.users import users_blu
app.register_blueprint(users_blu)

声明了蓝图目录以后的项目目录结构:

项目根目录/
├── application/ # 项目主要逻辑代码保存目录
| ├── settings/ # 项目配置存储目录
│   │ ├ dev.py # 开发阶段的配置文件
│   │ ├ prop.py # 生产阶段的配置文件
│   ├── __init__.py # 项目初始化文件
│   ├── static/ # 保存项目中所有的静态资源文件[img/css/js]
│   ├── apps/ # 保存项目中所有蓝图的存储目录
│   │   ├── users # 蓝图目录
│   │   │   ├── __init__.py # 蓝图的初始化问年间
│   │   │   └── views.py # 蓝图的视图函数文件
│   │   ├── __init__.py
├── manage.py # 项目的终端管理脚本文件

创建模型

1.在 users/model.py:

# coding=utf-8

from application import db

# 创建关系表,不再创建模型,一般用于表与表之间的多对多场景
"""
表关系变量 = db.Table(
"关系表表名",
db.Column('字段名', 字段类型, 字段选项), # 普通字段
db.Column("字段名", 字段类型, db.ForeignKey("表名.id")),
db.Column("字段名", 字段类型, db.ForeignKey("表名.id")),
)
""" achievement = db.Table(
'achievement',
db.Column('score',db.Numeric,comment='分数'),
db.Column('student_id',db.Integer,db.ForeignKey('student.id')),
db.Column('course_id',db.Integer,db.ForeignKey('course.id')) ) class Student(db.Model): '''学生信息''' __tablename__='student'
id = db.Column(db.Integer,primary_key=True,comment='主键id')
name = db.Column(db.String(64),index=True,comment='姓名')
sex = db.Column(db.Boolean,default=True,comment='性别')
class_number = db.Column(db.String(32),nullable=True,index=True,comment='班级')
age = db.Column(db.SmallInteger,comment='年龄')
description = db.Column(db.Text,comment='个性签名')
course = db.relationship(
'Course',
secondary=achievement,
backref = 'students', # 当外键反过来获取主键信息时,使用的字段名称,可以自定义,例如:course.students获取某个课程下所有的学生 lazy='dynamic',
) class Course(db.Model):
'''课程信息''' __tablename__='course'
id = db.Column(db.Integer,primary_key=True,comment='主键id')
name = db.Column(db.String(64),unique=True,comment='课程名称')

model表

2. 项目启动文件manage.py中:

from application import init_app  # 导入项目初始化函数

from application import db  # 从项目中引入数据库  该变量在 application/__init__.py 文件中

app = init_app('dev')

# 使用终端脚本工具启动和管理flask
manager = Manager(app) # 启用数据迁移工具
Migrate(app,db) # 添加数据迁移的命令到终端脚本工具中 manager.add_command('db',MigrateCommand) # 导入模型 [为了进行数据迁移]
from application.apps.users.models import *
@app.route('/') def index(): return 'ok' if __name__ == '__main__':
manager.run()

添加测试数据:

insert into student values
(1,"赵华",1,307,22,"对于勤奋的人来说,成功不是偶然;对于懒惰的人来说,失败却是必然。"),
(2,"程星云",1,301,20,"人生应该如蜡烛一样,从顶燃到底,一直都是光明的。"),
(3,"陈峰",1,504,21,"在不疯狂,我们就老了,没有记忆怎么祭奠呢?"),
(4,"苏礼就",1,502,20,"不要为旧的悲伤,浪费新的眼泪。"),
(5,"张小玉",0,306,18,"没有血和汗水就没有成功的泪水。"),
(6,"吴杰",1,307,19,"以大多数人的努力程度之低,根本轮不到去拼天赋"),
(7,"张小辰",0,405,19,"人生的道路有成千上万条, 每一条路上都有它独自的风景。")

静态文件和模板文件引入

1. users/__init__.py 文件中:

 2. users/views/py视图中:

 经过上面的过程可以得到大致的flask项目架构:

把该项目文件students该为 : flask_project_init  文件,以后大致的框架可以复用该结构。

使用该架构时注意的是:

  1. 配置文件中修改, 数据连接 库名 ,其他配置视具体情况做修改。

  2. 创建蓝图时,只需要拷贝users这个蓝图,再对其中的内容进行适当修改本文,具体操作本文中蓝图的创建。 

  3. 其他蓝图中的格式,可以参考,users 蓝图的方式,做操作。并修改蓝图名字。

flask_project_nit包:

获取:https://pan.baidu.com/s/1ZVDo0nVyj7FR4c78wnRWXA

提取码:ye3l

闪现信息[flash]:

使用后,只会出现一次的信息,叫“闪现信息”,用于在验证代码失败,或者一些只需要显示一次性提示的场景。

使用步骤:

视图中验证有误,则在显示模板之前设置flash

# 视图函数代码
from flask import flash flash("对不起,您尚未登录,请登录!")

模板代码:

# 模板代码
{% for message in get_flashed_messages() %}
<span>{{message}}</span>
{% endfor %}

04 flask 项目整体构建的更多相关文章

  1. 生产环境下Flask项目目录构建

    接触Flask已经有大半年了,本篇博客主要来探讨如何规范化生产环境下Flask的项目目录结构.虽然目录结构见仁见智,个人有个人的看法和习惯,但总的来说,经过很多人的实践和总结,还是有很多共同的意见和想 ...

  2. flask项目部署到阿里云 ubuntu16.04

    title: flask项目部署到阿里云 ubuntu16.04 date: 2018.3.6 项目地址: 我的博客 部署思路参考: Flask Web开发>的个人部署版本,包含学习笔记. 开始 ...

  3. Python Flask项目步骤

    构建flask项目步骤 步骤一:构建基础项目框架 创建manage.py文件 from flask import Flask app = Flask(__name__) ""&qu ...

  4. 通过VM虚拟机安装Ubuntu server部署flask项目

    1. VM安装Ubuntu server 14.04,系统安装完成后,首先安装pip工具方便之后的包安装,此处需先使用 apt-get install update,apt-get install u ...

  5. 《程序猿闭门造车》之NBPM工作流引擎 - 项目整体架构

    前言: 又是一年一度的圣诞节,可这关我什么事呢 :( ,好不容易周末了,还是说说NBPM吧,前不久我发布了一篇关于工作流的文章:<程序猿闭门造车>之NBPM工作流引擎 - 开篇,很多爱好工 ...

  6. flask项目结构(四)使用sqlalchemy和alembic

    简介 其实我不是啥正经人,错了,不是啥正经程序员,所能想到的估计也就码农一级吧,高级程序员,搞什么算法,什么人工智能,大数据计算…………离我还太遥远. 但是这并不妨碍我继续学习,继续写垃圾小程序. 反 ...

  7. flask项目结构(三)使用蓝图

    简介: Flask中的蓝图旨在针对这些情况: 把一个应用分解成一系列的蓝图.对于大型的应用是理想化的:一个项目能实例化一个应用, 初始化一些扩展,以及注册一系列的蓝图. 以一个 URL 前缀和/或子域 ...

  8. flask项目结构(二)创建flask,同步docker

    简介: 建立flask容易,那么部署就比较麻烦了,配这个,配那个,更新………… 所以我从构建,就考虑部署的问题,使用docker部署. 程序都打包进docker,本博客有相关文章. pycharn直接 ...

  9. (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2

    (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2 译者注: 原文来自:https://tech.amikelive.com/node-706/compre ...

随机推荐

  1. Python3 tkinter基础 Button bg 按钮的背景颜色

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  2. P2257 YY的GCD(莫比乌斯反演)

    第一次做莫比乌斯反演,推式子真是快乐的很啊(棒读) 前置 若函数\(F(n)\)和\(f(d)\)存在以下关系 \[ F(n)=\sum_{n|d}f(d) \] 则可以推出 \[ f(n)=\sum ...

  3. LightOJ 1258 Making Huge Palindromes(KMP)

    题意 给定一个字符串 \(S\) ,一次操作可以在这个字符串的右边增加任意一个字符.求操作之后的最短字符串,满足操作结束后的字符串是回文. \(1 \leq |S| \leq 10^6\) 思路 \( ...

  4. AtomicReference实现单例模式

    CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试. 乐观锁的一种实 ...

  5. 如何在 sublime text 中以当前文件目录打开 cmd

    需求描述 sublime 固定可以自己设置和添加新的编译环境,比如在我们写 js 的时候可能会添加 node 来对 js 文件进行运行.但是,这样做的结果是,我们只能看到运行结果.有时候还希望能做些其 ...

  6. 面试官:你了解Webpack吗?

    前言 大家好哟,这是第四篇面试官篇,估计还有个七八十篇面试文章(前端苦命). 这篇文章介绍了webpack核心概念以及如何使用. 开始吧! 概念 webpack的核心概念只要记住下面四个就够用了(除非 ...

  7. React native 开发如何使用阿里的icon

    首先是通过Text来引用的 但是区分是 familay <Text style={{fontFamily:'iconfont', fontSize:fontsize, color:this.st ...

  8. ZJOI-2017 R1游记

    无实力非既得利益的$xrdog$作为一名外卡选手去参加ZJOI2017啦... Day 0: 颓?(细节待填坑..) Day 1: 上午我来到讲课现场发现讲课内容是:搜索专题  QwQ不太清醒的我一下 ...

  9. memcached: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory

    1.在http://libevent.org/   下载libevent-2.0.22-stable.tar.gz 2.tar -zxvf libevent-2.0.22-stable.tar.gz ...

  10. Java——String,StringBuffer,StringBuilder

    String 一经创建,不可更改,每次更改都是创建新对象,销毁旧对象 StringBuilder 创建后可修改,多线程不安全 StringBuffer 创建后可修改,多线程安全 StringBuffe ...