Flask使用Blueprint进行多模块应用的编写

專 欄

夏轩,Python中文社区专栏作者。

博客:

http://blog.csdn.net/u012734441

  • 1、blueprint
  • 2、分模块后的结构
  • 3、业务模块
  • 4、运行
  • 5、总结

1、blueprint

在使用flask进行一个项目编写的时候,可能会有许多个模块,如一个普通的互联网sass云办公应用,会有用户管理、部门管理、账号管理等模块,如果把所有的这些模块都放在一个views.py文件之中,那么最后views.py文件必然臃肿不堪,并且极难维护,因此flask中便有了blueprint的概念,可以分别定义模块的视图、模板、视图等等,我们可以使用blueprint进行不同模块的编写,不同模块之间有着不同的静态文件、模板文件、view文件,十分方便代码的维护和管理,下面就是使用blueprint来进行上面用户管理、部门管理、账号管理模块的模拟编写,只涉及到api层面上,模板文件和静态文件就不写在上面了。

2、分模块后的结构

在进行分模块编写接口之后,以前提供的接口就不能写在一个views.py文件之中,具体结构如下所示:

  • dept: 这是部门管理模块,views是相应的接口文件。
  • user: 这是用户管理模块,同上,views是用户管理的相应接口。

其他的和之前的类似。

3、业务模块

3.1 dept模块

__init__.py:

# coding:utf-8

from flask import Blueprint

dept = Blueprint('dept', __name__,)

from app.dept import views

在这里,我们定义了dept blueprint对象,便于在views.py文件中应用,替代Flask对象。主要的接口 views.py:

# coding:utf-8

from app.dept import dept

from flask import jsonify

import json

dept_data = [

    {

        'name': '部门1',

        'id': 12345

    },

    {

        'name': '部门2',

        'id': 12346

    }

]



@dept.route('/<int:id>', methods=['GET', ])

def get(id):

    for dept in dept_data:

        if int(dept['id']) == id:

            return jsonify(status='success', dept=dept)



    return jsonify(status='failed', msg='dept not found')



@dept.route('/depts', methods=['GET', ])

def get_depts():

    data = {

        'status': 'success',

        'depts': dept_data

    }

    return json.dumps(data, ensure_ascii=False, indent=1)

提供两个接口,一个接口用于查询特定的部门,一个接口用于返回部门列表,dept对象我是模拟的部门数组,没有用models.py文件中dept对象,主要是在这一节中没有使用相应的orm框架,因此就没写相应的model,这个在随后中会涉及到。

另外一个,我在获取depts接口时,用的就不是jsonify方法了,而是内置的json.dumps转换为json对象,我之所以这样写,是因为jsonify如果要返回数组对象的话,必须要相应的对象实现一个方法返回json数据,或者将这个对象转成字典类型,然后循环遍历这个对象,比较麻烦,因此这里我就直接使用json.dumps来进行转换了。

在相应的路由注解上,我使用的就是dept.route,因此在定义了为dept的blueprint对象后,这里的作用相当于当初定义的app Flask对象,但其实是进行了view层的路由后,最终还是注册到了app上面,在代码层面上实现了不同模块之间的隔离。

3.2、user模块

user模块功能和代码大部分和dept相同,这里仅仅只贴出代码,不再描述具体的功能。

__init__.py:

# coding:utf-8

from flask import Blueprint

user = Blueprint('user', __name__,)

from app.user import views

views.py:

# coding: utf-8

from app.user import user

from flask import jsonify

import json

user_data = [

    {

        'id': 1,

        'name': '张三',

        'age': 23

    },

    {

        'id': 2,

        'name': '李四',

        'age': 24

    }

]
@user.route('/<int:id>', methods=['GET', ])

def get(id):

    for user in user_data:

        if user['id'] == id:

            return jsonify(status='success', user=user)



@user.route('/users', methods=['GET', ])

def users():

    data = {

        'status': 'success',

        'users': user_data

    }

    return json.dumps(data, ensure_ascii=False, indent=1)

3.3、run.py文件

最终Blueprint对象在run文件之中进行注册,如下:

# coding:utf-8

from app import app

from app.dept import dept

from app.user import user

app.register_blueprint(user, url_prefix='/user')

app.register_blueprint(dept, url_prefix='/dept')

if __name__ == '__main__':

    app.run()

app.register_blueprint在这里进行了Blueprint对象的注册和路由,在这里还有许多用法,如制定静态文件夹和模板文件夹等等,这些可以参考以下自己学习:使用蓝图的模块化应用

其他的我就没有再讲了,config.py和manager.py在这些简单的应用中还无需用到,讲到后面再来说这些的作用。

4、运行

启动run文件,进行运行,请求

http://localhost:5000/user/

结果:

第一个接口请求成功:

请求第二个接口:

http://localhost:5000/user/users

接口同样请求成功,在这里dept模块就不去请求,结果是类似的。

5、总结

  • Blueprint其实本身只是对view上的接口进行了注册,然后整体挂载在app上,Blueprint本身的目的就是组织多模块的平行共存,避免直接在app上注册view,其实更多的只是方便开发和代码的维护,因为最终所有的views上的接口都仍然是直接挂载在app上,其实对应整个应用来说,没有什么明显的区别。
  • Flask 中的Blueprint不是一个可插拨的应用,因为它不是一个真正的应用,而是一套可以注册 在应用中的操作,并且可以注册多次。
  • 同时在这里,我们不能使用多个flask对象来管理和注册,因为这样会导致每个flask对象都有一个自己的配置,不好管理。
  • 使用Blueprint,应用会在Flask层中进行管理,共享配置,通过注册按需改变应用 对象。Blueprint的缺点是一旦应用被创建后,只有销毁整个应用对象才能注销lueprint。
  • 综合以上,简单来说,Blueprint就是通过url找到view的一套机制,并没有太过于复杂的逻辑。

原文发布于微信公众号 - Python中文社区(python-china)

原文发表时间:2017-03-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端知识分享

第218天:Angular---模块和控制器

所有需要ng管理的代码必须被包裹在一个有ng-app指令的元素中 ng-app是ng的入口,表示当前元素的所有指令都会被angular管理(对每一个指令进行分析...

10320
来自专栏Java帮帮-微信公众号-技术文章全总结

day27.MongoDB【Python教程】

集合:类似于关系数据库中的表,储存多个文档,结构不固定,如可以存储如下文档在一个集合中

12830
来自专栏从流域到海域

《笨办法学Python》 第15课手记

《笨办法学Python》 第15课手记 本节课涉及i新内容,请仔细阅读本节内容,尤其是作者的说明和常见问题解答。 原代码如下: from sys import ...

20650
来自专栏深度学习与计算机视觉

Python3 import 与 from...import

在 python 中,用 import 或者 from…import 来导入相应的模块。模块其实就是一些函数和类的集合文件,它能实现一些相应的功能,当我们需要使...

25570
来自专栏测试驿栈

Jmeter(三十五)_精确实现网页爬虫

meter实现了一个网站文章的爬虫,可以把所有文章分类保存到本地文件中,并以文章标题命名

14420
来自专栏Golang语言社区

Go语言Goroutine与Channel内存模型

Go语言内存模型规定了在一个goroutine中一个变量的读取的情况下,确保能够观察到在其他另外goroutine中写入同样变量的值。也就是说,如果在多个gor...

36760
来自专栏从零开始学自动化测试

pytest文档19-doctest测试框架

doctest从字面意思上看,那就是文档测试。doctest是python里面自带的一个模块,它实际上是单元测试的一种。 官方解释:doctest 模块会搜索那...

16820
来自专栏性能与架构

Redis 实现安全队列

Redis的列表数据结构可以让我们方便的实现消息队列 例如用 LPUSH(BLPUSH)把消息入队,用 RPOP(BRPOP)获取消息 绝大部分的情况下,这...

45750
来自专栏FreeBuf

Flask Jinja2开发中遇到的的服务端注入问题研究

0×00. 前言 作为一个安全工程师,我们有义务去了解漏洞产生的影响,这样才能更好地帮助我们去评估风险值。本篇文章我们将继续研究Flask/Jinja2 开...

24150
来自专栏未闻Code

Tenacity——Exception Retry 从此无比简单

Python 装饰器装饰类中的方法这篇文章,使用了装饰器来捕获代码异常。这种方式可以让代码变得更加简洁和Pythonic。

18610

扫码关注云+社区

领取腾讯云代金券