启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情
之前聊过了Flask的基本功能,基于之前聊过的功能,我们可以实现前端页面的加载,前端请求的处理,后端的请求的处理,表单校验,数据库建模,后端响应,会话处理,但是都是基于单个文件进行举例的,并没有一个完整的项目格式,并且还需要注意一个点,就是实际上的项目往往不是由一个大的功能模块组成的,而是有很多子模块组成的,并且也不会让一个文件来负责从建模到视图到路由的所有的功能。所以今天聊聊Flask项目结构。
这里以一个博客为例子。
MVC
首先这里需要强调的是MVC,一种设计模式,并不是flask独有的,而是所有编程的一种设计方案,就是按照:
M(models):模型,数据库映射部分。
V(views):视图,服务器功能。
C(controls):控制器,管理请求和视图的关系(这里还有其他的理解,但是不影响今天功能开发。)
的功能划分,把项目分成三个部分开发,这样思路也比较清晰,并且也方便代码复用。安装MVC,我们可以把flask项目分成下面的格式。
1、项目创建文件
2、项目配置文件
3、项目启动文件
4、项目路由文件
5、项目功能文件
6、项目模型文件
按照这个思路来创建项目架构:
| 文件 | 对应功能 |
|---|---|
| init.py | 项目创建文件 |
| models.py | 项目模型文件 |
| settings.py | 项目配置文件 |
| urls.py | 项目路由文件 |
| views.py | 项目功能文件 |
| run.py | 项目启动文件 |
首先来串通这些文件,让项目先跑起来。
init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from BlogPro.settings import Config
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
settings.py
class Config:
SECRET_KEY = "hello world" #加密配置
#数据库配置
SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:@127.0.0.1:3306/test'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
这里需要注意的是app.config.from_object是加载配置文件
views.py
def index():
return "hello word"
urls.py
from BlogPro import app
from BlogPro.views import *
app.add_url_rule("/",endpoint="index",view_func=index)
models.py
from BlogPro import db
class BlogModel(db.Model):
id = db.Column(db.Integer, primary_key = True,auto_increment = True)
title = db.Column(db.String(32))
author = db.Column(db.String(32))
content = db.Column(db.Text)
public_time = db.Column(db.DateTime)
description = db.Column(db.String(300))
run.py
from BlogPro.urls import app
from BlogPro.models import db
with app.app_context():
db.create_all() # 同步数据库
app.run(debug=True)
蓝图
上面完成了MVC的划分,但是就那博客来说,至少会有用户部分,文章部分,这两个部分的逻辑相互独立。flask为了这样的使用场景提供了蓝图,所谓的蓝图就是一个完整的子功能。可以以插件的形式安装到服务当中。
蓝图的使用步骤如下:
定义蓝图
定义一个Articles包,在__init__.py当中进行蓝图定义
from flask.blueprints import Blueprint
api = Blueprint("article_api",__name__,url_prefix="/api/articles")
from BlogPro.Articles.urls import *
这里蓝图的三个参数:
参数1:蓝图的名称
参数2:蓝图的位置
参数3:蓝图的路由
使用蓝图
在Articles包当中定义urls.py路由文件和views.py视图文件
urls.py
from BlogPro.Articles import api
from BlogPro.views import *
api.add_url_rule("/",endpoint="index",view_func=index)
views.py
def index():
return "hello word"
服务加载蓝图
BlogPro\BlogPro_init_.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from BlogPro.settings import Config
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
#加载部分
from BlogPro.Articles import api as article_api
app.register_blueprint(article_api)
return app
这里和之前有几处修改,需要注意:
1、在文件当中定义函数是为了方便后续的配置和管理
2、db = SQLAlchemy() 和 db.init_app(app)是另外一种数据库绑定的方法
3、加载部分只是两句
from BlogPro.Articles import api as article_api
app.register_blueprint(article_api)
那么现在的目录变成了这样:
这里新增了3个文件:
BlogPro/Articels/init.py
BlogPro/Articels/urls.py
BlogPro/Articels/views.py
代码在上面
修改了2个文件:
BlogPro/BlogPro/init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from BlogPro.settings import Config
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
from BlogPro.Articles import api as article_api
app.register_blueprint(article_api)
return app
BlogPro/run.py
from BlogPro import create_app
from BlogPro.models import db
app = create_app()
with app.app_context():
db.create_all() # 同步数据库
app.run(debug=True)
整个蓝图理解起来会比较麻烦,但是如果项目功能模块多的情况下还是相当有用的。