Python-Flask 蓝图以及钩子函数(5)


官方解释:Blueprint 是一种组织一组相关视图及其他代码的方式。与把视图及其他 代码直接注册到应用的方式不同,蓝图方式是把它们注册到蓝图,然后在工厂函数中 把蓝图注册到应用。

Flaskr 有两个蓝图,一个用于认证功能,另一个用于博客帖子管理。每个蓝图的代码 都在一个单独的模块中。使用博客首先需要认证,因此我们先写认证蓝图。

个人自己的理解:蓝图是路由的另一种方式,一个项目中会有很多不同的功能,如果将这些功能的视图写在一个app.py文件里面的话,会显得很臃肿,不易阅读,也不易后期维护。一般来说会根据不同的功能拆分成很多模块,比如用户管理、权限管理、商品管理、库存管理、订单管理等等,每一个模块都有自己对应的一个路由文件,将这些路由注册到一个公共的对象里面去,这个对象可以理解为蓝图,然后再讲蓝图注册到app里面去,也就是flask对象里面去,就完成了视图、客户端、服务器的绑定。通过这种方式,,开发者能够把他们的应用拆分成不同的组件。 在我们的架构中,,蓝图的作用类似于控制器的效果。

一、初识蓝图的页面结构

创建蓝图前的写法:app.py文件包含多个功能模块的视图
在这里插入图片描述
创建蓝图后:
用户管理功能对应的视图文件
在这里插入图片描述
apps包下的初始化文件,用于创建创建flask对象,只要其他地方加载这个包下面的文件会自动加载该文件。
在这里插入图片描述
app.py文件
app.py文件

从上面对比可以看出,引入蓝图后,启动文件app.py内容就显得很简洁,并且根据功能分成不同的模块,可阅读性强。同一功能的路由以及视图函数都分门别类的存在相应功能的模块中,后期维护,添加,修改内容也更方便,可维护性强。

二、创建蓝图的步骤

蓝图的使用步骤分为三步:

  • 创建一个蓝图对象
    • user_bp = Blueprint(‘user’, name)
    • 有两个参数:
      • 一个是蓝图的名称
      • 一个是蓝图所在的模块
  • 在这个蓝图对象上进行操作:注册路由,指定静态文件夹, 注册模板过滤器
    • 注册路由: 通过@user_bp.route(’/’)装饰器
    • 指定静态文件夹:因为默认是在app.py文件中创建flask对象的,flask对象底层有一些默认的配置,指定templates模板文件夹路径,static静态文件夹路径等信息。默认的templates路径是与app.py同级的文件夹下,如果创建flask对象迁移至apps或者其他文件夹下的话,需要在创建flask对象时,通过template_folder=’…/templates’参数指定模板文件夹的路径,这时视图函数中返回的模板页面才能找得到。
@user_bp.route('/')
def user_center():
    return render_template('user/show.html', users=users)
  • 在应用对象上注册蓝图对象
    • 通过第二步将路由和蓝图绑定后,这时蓝图还未与模板建立联系,也就还未与客户端建立联系,因此还需将应用对象(flask对象)上注册该蓝图。
    • 通过app.register_blueprint(user_bp) 将蓝图对象绑定到app上,绑定前需要先将蓝图导入到该文件中。
      在这里插入图片描述

三、钩子函数

对于视图函数而言,还有四种方式根据不同的场景需求在视图函数返回前后做一些定制化的处理来完成业务的开发需求,实现的方式叫做钩子函数。最常见的有以下四种钩子函数,分别是在视图函数处理前,处理后,返回前,对请求做的处理。

before_first_request                     第一次请求处理前执行, 后续请求到来不执行, 只执行一次

before_request                             每个请求到来前都执行一次

after_request                                请求处理后无异常执行该钩子

teardown_request                        请求处理后, 无论存在异常与否, 都会执行该请求钩子
首先,我对蓝图的理解相对通俗,就是觉得蓝图对于视图方法模块化、大项目协同开发过程中的一个很好的工具. 1.下图是我们通常情况下使用的项目组织结构 看一下视图方法: #views.py 1 from app import app 2 3 4 @app.route('/user/index') 5 def index(): 6 return 'user_index' 7 8 @app.route('/user/show') 9 def show(): 10 return 'user_show' 11 12 @app.route('/user/add') 13 def add(): 14 return 'user_add' 15 16 @app.route('/admin/index') 17 def adminindex(): 18 return 'admin_index' 19 20 @app.route('/admin/show') 21 def adminshow(): 22 return 'admin_show' 23 24 @app.route('/admin/add') 25 def adminadd(): 26 return 'admin_add' #从视图方法中,我们看到有6个视图,分别对应admin,user两个不同用户的3个功能index,add,show. 这样写显然没问题,但是明显与python提倡的模块化,优雅的代码特点相违背,即不是很pythonpython代码. 让我们在这里假想两个问题: 1.如果admin和user不止只有3个功能呢,比如好几百个,导致views的代码量已经达到了上万行? 2.如果我们有多个同事分工开发admin,user和其它可能的模块呢,都同时往一个views里写代码吗,在做版本控制时,提交过程中频繁出现提交冲突了怎么办? 3.加入我们要抛弃admin或者user功能块时怎么办,要一一手动删除所有admin或是user相关的代码吗,这样当然可以,但是会不会太low呢? 当然根据Pythonic特点,我们肯定希望尽可能的把代码尽量的模块化,让我们的代码看起来更加的优雅和顺畅,这个时候flask.Blueprint(蓝图)就派上用场了 什么是蓝图? 一个蓝图定义了可用于单个应用的视图,模板,静态文件等等的集合。 我什么时候会用到蓝图蓝图的杀手锏是将你的应用组织成不同的组件,比如把这里的admin,user相关的视图方法分为两个组件,一个是admin组件,一个是user组件.这时我们可以 创建两个蓝图实现这两个独立的组件. 2.我们如何使用蓝本将上述的视图方法看上去更加pythonic呢? 由于上面的例子中只有两个组件(模块)admin,user,我们可以创建名为admin.py和user.py的两个文件,分别在里面创建两个蓝图的实例对象admin,user. 直接上代码: #admin.py #admin.py from flask import Blueprint,render_template, request admin = Blueprint('admin',__name__) @admin.route('/index') def index(): return render_template('admin/index.html') @admin.route('/add') def add(): return 'admin_add' @admin.route('/show') def show(): return 'admin_show' #要想创建一个蓝图对象,你需要import flask. Blueprint() 类并用参数 name 和 import_name 初始化。import_name通常用 __name__ ,一个表示当前模块的特殊的Python变量,作为 import_name 的取值。 #user.py from flask import Blueprint, render_template, redirect user = Blueprint('user',__name__) @user.route('/index') def index(): return render_template('user/index.html') @user.route('/add') def add(): return 'user_add' @user.route('/show') def show(): return 'user_show' 好了,视图函数已经分开了,我们如何使用它们的呢?再来看一下我们的views.py变成了什么样吧? #views.py from app import app from .admin import admin from .user import user #这里分别给app注册了两个蓝图admin,user #参数url_prefix='/xxx'的意思是设置request.url中的url前缀, #即当request.url是以/admin或者/user的情况下才会通过注册的蓝图的视图方法处理请求并返回 app.register_blueprint(admin,url_prefix='/admin') app.register_blueprint(user, url_prefix='/user') #现在我们的views是否已经变得很简单了呢?顺便回答第三个问题,如果想弃用某一个组件(模块)我们只需要相对应的注释掉给app注册蓝图的行即可. #细心的伙伴还可以发现,在views.py中在使用默认endpoint的前提下,我们是没有办法使用同一个视图方法名的(当然我们也不建议在同一个文件中有两个视图方法名相同, #尽管指向他们的request.url不同),但是使用了蓝图之后我们就可以在不同模块中使用相同的方法名了,例如add,show.. 3.到此我们就可以通过浏览器测试我们的程序 4.附上使用蓝图后的项目组织结构 当然如果项目不大的话就没有什么必要使用蓝图了,甚至我们可以把除了所有css,js,html的代码都写到一个文件中去,这里我们不在举例,说明.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值