Flask-基本应用搭建模式

来源:互联网 发布:手机搞笑视频软件 编辑:程序博客网 时间:2024/06/04 18:15

1. 开发工具

不管Windows还是Linux都可以使用PyCharm作为IDE,功能齐全,使用方便。

2. 创建VirtualEvn

如果使用PyCharm就不用再在命令行创建ve了,直接新建工程,并选择create virtualevn,命名并选择保存路径即可。

3. 安装包依赖包

在PyCharm中通过菜单[File]->[Settings]->[Project:youprojectname]->[Project Interpreter],可查看该环境下已安装的包,并点击“+”图标可以添加新包,也可以在此删除包。根据一般Flask工程需求,我们需要安装的包有:
  • Flask(包含了Werkzeug和Jinja2)
  • Flask-SQLAlchemy
  • Flask-MySQLdb
  • Flask-Migrate
  • Flask-script
安装这些包的时候可能会附带安装其依赖包。

4. 工程目录结构

一个典型的工程目录结构如下:
+program    //项目目录    +app                  //应用程序目录        +view1            //应用模块1            -__init__.py  //蓝图定义,过滤器定义,上下文函数变量定义            -view.py      //应用模块1的具体处理函数        +view2            //应用模块2        +models           //数据模型            -model1.py    //定义具体的数据模型类        +static           //静态文件(css,js,images等)        +templates        //模板目录,存放页面模板,可用子目录区分不同应用的模板文件        -__init__.py      //定义SQLAlchemy的实例,并定义create_app函数用于创建Flask应用及相关初始化    +log                  //日志文件夹    +venv                 //环境目录    +migrations           //数据迁移,自动生成的,不需管理    -config.py            //系统配置文件(数据库,密钥等)    -manage.py            //管理数据迁移    -run.py               //启动app

5. config.py

import osbasedir = os.path.abspath(os.path.dirname(__file__))class Config:    DEBUG = False    TESTING = False    SECRET_KEY = os.environ.get('SECRET_KEY') or \                 b'\x90\x87d\xcfk\xbd\x81\xa2\\G\xb2\x9a\x8d\xe5\xb5c\xa3\xbd\x85\x8c\x8c\x86\xbc`\x94ZM\xf5\xdaN\x92'    SQLALCHEMY_COMMIT_ON_TEARDOWN = True    @staticmethod    def init_app(app):        passclass DevelopmentConfig(Config):    DEBUG = True    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \        'sqlite:////database/flaskdb.db'    SQLALCHEMY_TRACK_MODIFICATIONS = Trueclass TestingConfig(Config):    TESTING = True    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \        'sqlite:////database/flaskdb.db'    SQLALCHEMY_TRACK_MODIFICATIONS = Trueclass ProductionConfig(Config):    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \        'mysql://user:password&lp@localhost:3306/flaskdb'    SQLALCHEMY_TRACK_MODIFICATIONS = Trueconfig = {    'development':DevelopmentConfig,    'testing':TestingConfig,    'production':ProductionConfig,    'default':DevelopmentConfig,}

6. app/__init__.py

from flask import Flask, render_template, loggingfrom flask_sqlalchemy import SQLAlchemyfrom logging.handlers import TimedRotatingFileHandlerfrom config import configdb = SQLAlchemy()def create_app(config_name):    app = Flask(__name__)    app.config.from_object(config[config_name])        #添加日志处理    mylog = TimedRotatingFileHandler('log/mylog.log', 'D')    mylog.setLevel(logging.DEBUG)    mylog.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))    app.logger.addHandler(mylog)    #初始化DB    db.init_app(app)    #注册蓝本    from app.view1 import view1 as view1_blueprint    app.register_blueprint(view1_blueprint, url_prefix='/view1')    #附加路由,自定义错误页面        return app

7. run.py

import osfrom app import create_appapp = create_app(os.getenv('FLASK_CONFIG') or 'default')if __name__ == '__main__':    app.run()

8. manage.py

import osfrom app import create_app, dbfrom flask_script import Managerfrom flask_migrate import Migrate, MigrateCommand'''manager使用说明:命令格式:python3 manager.py db [command]在PyCharm中可对manager.py编辑参数 db [command]command说明:init-初始化数据库迁移(自动生成migrations目录及文件),仅在第一次使用migrate-生成迁移数据,自动根据model变化生成迁移数据文件,含版本控制upgrade-执行升级操作,将变动的表结构提交到数据库,保留数据库原数据downgrade-执行降级操作, 相当于撤回本次升级操作'''app = create_app(os.getenv('FLASK_CONFIG') or 'default')migrate = Migrate(app, db)manager = Manager(app)manager.add_command('db', MigrateCommand)manager.run()

9. model1.py

from app import dbclass Book(db.Model):    __tablename__ = 'book'    id = db.Column(db.Integer, primary_key=True)    name = db.Column(db.String(50), unique=True)    pub_date = db.Column(db.DateTime)    def __init__(self, name):        self.name = name    def __repr__(self):        return "<Book %r>" % self.name

10. app/view1/__init__.py

from flask import Blueprint#蓝本定义view1 = Blueprint('view1', __name__)from app.view1 import view#自定义过滤器@book.app_template_filter('reverse')def reverse_filter(s):    return s[::-1]#自定义上下文过程,可返回一个字典,包含模板可用的变量和函数@book.context_processordef utility_processor():    rt = dict()    def format_date(date):        return date.strftime('%Y{y}%m{m}%d{d}').format(y='年', m='月', d='日')    rt['formatdate'] = format_date    def format_date2(date):        return date.strftime('%Y-%m-%d')    rt['formatdate2'] = format_date2    rt['xname'] = 'other strings'    return rt

11. app/view1/view.py

from flask import render_template, flash, current_appfrom app.models.model1 import Bookfrom . import view1@view1.route('/', methods=['GET'])def index():    books = Book.query.all()    return render_template('book/bookindex.html', books=books)@view1.route('/index2', method=['GET', 'POST'])def index2():    books = Book.query.all()    return  render_template('book/bookindex2.html', books=books)

12. app/templates/book/bookindex.html,layout.html

layout.html
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>详细页面</title>    <link rel="stylesheet" href="/static/main.css"/></head><body>{% with messages = get_flashed_messages(with_categories=true) %}{% if messages %}<ul>    {% for category, message in messages %}    <li class="{{ category }}">{{ message }}</li>    {% endfor %}</ul>{% endif %}{% endwith %}{% block body %}{% endblock %}</body></html>
bookindex.html
{% extends "book/layout.html" %}{% block body %}<h1><a href="{{url_for('index')}}">首页</a> </h1>{%for book in books%}<li>{{ book.name | reverse }}==={{ formatdate(book.pub_date) }}</li>{%endfor%}{% endblock %}