zoukankan      html  css  js  c++  java
  • 04 flask 项目整体构建

    本文主要的目标是创建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
    View Code

    增加数据库配置

    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,"人生的道路有成千上万条, 每一条路上都有它独自的风景。")
    View Code

    静态文件和模板文件引入

    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 %}
  • 相关阅读:
    如何在solution中添加一个test case
    Solution中的auto test case组织方式
    如何使用SPY++查找
    VS2012如何更新下载TFS上面的代码到本地
    Mita和Maui
    Fuzzy test
    RSS FEED的应用
    iscroll横向滑动(当前页状态标记自动变化)
    jquery技巧(持续更新。。)
    jquery前端性能优化(持续添加。。。)
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10686446.html
Copyright © 2011-2022 走看看