当前位置: 代码迷 >> 综合 >> python flask使用蓝图 Blueprint
  详细解决方案

python flask使用蓝图 Blueprint

热度:78   发布时间:2023-10-09 22:39:32.0

随着flask程序越来越复杂,我们需要对程序进行模块化的处理,之前学过python的模块化管理,于是针对一个简单的flask程序进行模块化处理。
简单来说,蓝图 Blueprint是一个存储试图方法的容器,这些操作在这个蓝图 Blueprint被注册到一个应用之后就可以被调用,Flask可以通过蓝图 Blueprint来组织URL以及处理请求。
蓝图 Blueprint具有如下属性:
一个项目具有多个蓝图 Blueprint。
可以将一个蓝图 Blueprint注册到任何一个未使用的URL下,比如“/”、“/sample”或者子域名
在一个应用中,一个模块可以注册多次
蓝图 Blueprint可以单独具有自己的模块,静态文件或者其他的通用操作方法,他并不是必须要实现应用的视图和函数
在一个应用初始化时,就应该要注册需要使用的蓝图 Blueprint
但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

Blueprint对象用起来和一个应用/Flask对象差不多,最大的区别在于一个 蓝图对象没有办法独立运行,必须将它注册到一个应用对象上才能生效
使用蓝图的四大步骤:
1.创建一个蓝图的包,例如在__init__.py文件中创建蓝图对象

api = Blueprint('api', __name__)

2.在这个蓝图目录下,创建xx.py文件,保存当前蓝图使用的视图函数

@api.route('/query/recognize', methods=['POST'])
def recognize():if request.is_json:data = request.get_json()attributes = ['query', 'tableNames']if not all_field_in_keys(attributes, data.keys()):abort(errors.bad_request("请求格式错误"))query = data['query']table_names = data['tableNames']tables, kvs = query_controller.recognize_query(query, table_names)rst = ResponseModel({
    'tableNames': tables, 'kvs': kvs})return Response(rst.attr_dict())else:abort(errors.bad_request("请求格式错误"))

3.在蓝图的包,例如在__init__.py文件中引入xx.py中所有的视图函数

from flask import Blueprint
from server.others.constants import DEPLOY_MODULEapi = Blueprint('api', __name__)if 'laws' in DEPLOY_MODULE:from . import search, uploadif 'query' in DEPLOY_MODULE:from . import query

4.在主程序应用.py文件中的app对象上注册这个api蓝图对象

from .api import api as api_blueprintapp.register_blueprint(api_blueprint)

当这个应用启动后,通过/api/可以访问到蓝图中定义的视图函数

运行机制
蓝图是保存了一组将来可以在应用对象上执行的操作,注册路由就是一种操作
当在app对象上调用 route 装饰器注册路由时,这个操作将修改对象的url_map路由表
然而,蓝图对象根本没有路由表,当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项
当执行app对象的 register_blueprint() 方法时,应用对象将从蓝图对象的 defered_functions 列表中取出每一项,并以自身作为参数执行该匿名函数,即调用应用对象的 add_url_rule() 方法,这将真正的修改应用对象的usr_map路由表

蓝图的url前缀
当我们在应用对象上注册一个蓝图时,可以指定一个url_prefix关键字参数(这个参数默认是/)
在应用最终的路由表 url_map中,在蓝图上注册的路由URL自动被加上了这个前缀,这个可以保证在多个蓝图中使用相同的URL规则而不会最终引起冲突,只要在注册蓝图时将不同的蓝图挂接到不同的自路径即可
url_for在使用时,如果要生成一个蓝图里面的视图对应的路由地址,则需要声明当前蓝图名称+视图名称