Flask项目的代码组织方式

来源:互联网 发布:海鸥手表怎么样 知乎 编辑:程序博客网 时间:2024/06/06 05:21

写在前言:  "分与合”的思想贯穿了所有的软件设计,不管是框架、设计模式还是系统架构。


       Flask和Django是Python下做Web开发的两个主要框架,相比Django而言,Flask更加轻盈、灵活。Django采用app的概念来组织代码,允许你添加自己app package,每个app只需专注于自己的功能开发(model/view/template/URL路由),当服务跑起来后,框架会根据你注册的app来进行分发。

      然而Flask则没有如此清晰的组织方式,那么Flask下如何有效的组织代码?这是本文希望能介绍的关键点,当然,更希望能借此传达“分与合”的思想。有效组织代码的目的,在于增强代码的可读性、可维护性、可扩展性,通过“分”将不同功能模块拆解到不同文件组织中,再用“合”的方式将各个模块有效组织起来,完成服务功能。

      任何一个语言/框架,我们大多数会从Hello World开始,然而写一个Hello World往往很简单,但是想用好的话,就意味着需要花更多的时间来打磨。当我们创建一个Flask工程时,基础的组织形式如下:

from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world():    return 'Hello World!'if __name__ == '__main__':    app.run()

     工程目录下只有一个py文件,我们姑且称这种组织形式为单一模块形式。flask_travel.py中包含了所有的代码:app创建、路由配置、view函数、开发环境下的runserver等等,使用python flask_travel.py就可以让服务在本地跑起来了。这种方式,适合做一些简单的demo或者非常简单的Web服务,当项目中的功能越来越多时,必然要进行拆分,将flask_travel.py中的功能分到不同的文件中,而python的文件组合往往都离不开package的概念,所以就有了下面这种优化后的组织方式:


      相比单一模块组织形式,这个组织形式要更加清晰了,且称之为包组织形式。当我们完成这样的分解后,如何在不同的文件中进行引用和配置,最终实现将服务启起来?下面将做详细分析:

1. config.py,用于添加配置项,比如针对SQLAlchemy的配置:

SQLALCHEMY_DATABASE_URI = 'mysql://user:password@localhost/flask_travel'

需要在flask_travel/__init__.py中进行注册,让app发现这些配置项:

app.config.from_object('config')

2. run.py,用于启动开发阶段的服务,即:

from flask_travel import appapp.run(debug=True)
3. flask_travel/__init__.py完成app的创建及所有的功能关联工作:

# -*- coding: utf-8 -*-from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config.from_object('config')db = SQLAlchemy(app)from . import views

4. flask_travel/views.py负责view的功能和路由的配置,需要引用flask_travel包中的app:

from . import app@app.route('/')def hello_world():    return 'Hello, World!'

5. flask_travel/models.py负责数据库的model,需要引用flask_travel包中的db:

# -*- coding: utf-8 -*-from flask_travel import dbclass User(db.Model):    id = db.Column(db.Integer, primary_key=True)    nickname = db.Column(db.String(64), index=True, unique=True)    email = db.Column(db.String(120), index=True, unique=True)    phone = db.Column(db.String(13), index=True, unique=True)
6. static和template下主要放静态网页文件js/css等和JinJa2模板文件。

至此,通过python run.py便可以在本地启动服务了。

      包组织形式有效的拆解了各功能块,使得不同的功能可以在不同的文件中书写,然而随着业务功能的增加,views和models两个文件的代码会不断膨胀,此时该如何进一步拆解文件,实现不同的功能在不同组织下的views和models中实现?Flask提供了Blueprint的功能,允许为一个application注册多个blueprint,这个功能为我们进一步分离各个组件功能提供了可能,如下所示为Blueprint组织形式


      在上面的Blueprint组织形式中,hello_world是一个blueprint,其下面的路由都是注册在该blueprint中的,然后在flask_travel中将hello_world注册到app中,你可以创建更多的blueprint。

1. hello_world/__init__.py,创建blueprint:

# -*- coding: utf-8 -*-from flask import Blueprinthello_world = Blueprint('hello_world', __name__, url_prefix='/hello-world')from . import views

2. hello_world/views.py,完成view功能和路由配置:

# -*- coding: utf-8 -*-from . import hello_world@hello_world.route('/')def hello_world():    return 'Hello, World!'

3. flask_travel/__init__.py,创建app,并完成各功能的关联:

# -*- coding: utf-8 -*-from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyfrom .hello_world import hello_worldfrom flask_migrate import Migrateapp = Flask(__name__)app.config.from_object('config.default')app.register_blueprint(hello_world)db = SQLAlchemy(app)migrate = Migrate(app, db)

      同样,你可以通过python run.py来启动本地服务。

      Blueprint组织形式有点类似Django的app组织方式,但是二者并不完全相同,不过对于绝大多数Flask应用,包组织方式或Blueprint的组织方式已经足够应付了。



(全文完,本文地址:http://blog.csdn.net/zwgdft/article/details/52854121)

Bruce 2016/10/18



0 0
原创粉丝点击