基于多模块博客项目搭建Flask蓝图架构

854 阅读3分钟

启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

之前聊过了Flask的基本功能,基于之前聊过的功能,我们可以实现前端页面的加载,前端请求的处理,后端的请求的处理,表单校验,数据库建模,后端响应,会话处理,但是都是基于单个文件进行举例的,并没有一个完整的项目格式,并且还需要注意一个点,就是实际上的项目往往不是由一个大的功能模块组成的,而是有很多子模块组成的,并且也不会让一个文件来负责从建模到视图到路由的所有的功能。所以今天聊聊Flask项目结构。

这里以一个博客为例子。

MVC

首先这里需要强调的是MVC,一种设计模式,并不是flask独有的,而是所有编程的一种设计方案,就是按照:

M(models):模型,数据库映射部分。

V(views):视图,服务器功能。

C(controls):控制器,管理请求和视图的关系(这里还有其他的理解,但是不影响今天功能开发。)

的功能划分,把项目分成三个部分开发,这样思路也比较清晰,并且也方便代码复用。安装MVC,我们可以把flask项目分成下面的格式。

1、项目创建文件

2、项目配置文件

3、项目启动文件

4、项目路由文件

5、项目功能文件

6、项目模型文件

按照这个思路来创建项目架构:

image-20221203210401951.png

文件对应功能
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)

那么现在的目录变成了这样:

image-20221203215158382.png

这里新增了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)

整个蓝图理解起来会比较麻烦,但是如果项目功能模块多的情况下还是相当有用的。