Flask框架钩子函数使用方式及应用场景分析

简介:

在正常执行的代码前中后,强行插入执行一段你想要实现的功能的代码,这种函数就叫做钩子函数。钩子函数就是等同于高速公路上的收费站,进高速之前给你一个卡,并检查你是否超重。离开之前收你,也可以拦住你安检一下。

一、基础概念:

 ●  request: Flask的请求上下文,包含请求变量如:method、args、form、values、endpoint、headers、remote_addr都是比较常用的。
 ●  session:Flask的请求上下文,用于存放用户的会话信息。

 ●  current_app:Flask的应用上下文,返回当前app的方法和属性,可以勉强理解为类全局变量。

二、七种钩子

第一个钩子:@app.before_first_request

只在第一次请求之前执行,也就是启动项目,不会执行,只会在第一次有人发起请求时,才会触发这个钩子中的代码。

全局场景:可以带动一个异步执行的函数,进行一些健康指标的检查,如果发现有异常,则截断后续的请求,将整个Flask应用停止。


@app.before_first_request
def first_request():
print('只有在处理第一次请求之前执行')

第二个钩子:@app.before_request

这是最重要的一个钩子,在每次请求之前可以注入你要的逻辑的钩子。在app下的before_request,过滤的是全部请求。结合Blueprint的before_request,则是过滤该蓝图下的请求。所以我们就可以进行分层过滤,定制化过滤。

全局的场景包含:共享session的鉴权函数、请求黑白名单过滤、根据endpoint进行请求j等。

蓝图场景包含api的请求必填字段校验,是否json请求校验,请求的token校验等。


api = Blueprint('api', __name__)
requied = {
'api.register':['email','username','password']
}

# 钩子 在请求执行之前
@api.before_request
def before_request():

# 请求格式校验拦截
if not request.is_json:
return '带参数请求请使用json格式'
# 缺少必填参数拦截
try:
if request.endpoint in requied:
if request.method == "POST":
missparam_list = [x for x in requied[request.endpoint] if x.encode('utf8') not in list(parse.parse_qs(request.data).keys())]
else:
missparam_list = [x for x in requied[request.endpoint] if x not in request.json.keys()]

if len(missparam_list) > 0:
return "缺少以下参数:{0}"
except Exception as e:
app.logger.error(e)
return "{0}".format(e)

第三个钩子:@app.errorhandler

当访问应用出错时,根据错误响应码,进行一些定制化的操作,如返回一个可爱的404页面。也可以进行一些报错登记。

场景:可以用redis进行错误请求计数,超过一定量则进行告警。可以重定向到一个定制的错误代码页面等。


@app.errorhandler(404)
def page_not_found(error):
return render_template('otherpage/404.html'),404

第四个钩子:@app.context_processor

这个钩子也很实用,是将一些常量按字典的格式返回,则可以在jinja2的模版中引用。这样就不用在每个视图函数中都render_template中重复去写一次。代码更简洁。

场景:在html中,直接用{{jidan}}就会在页面显示yao。等同于app.add_template_global('yao',''jidan)


@app.context_processor
def context_rocessor():
return {'jidan':'yao'}

第五个钩子:@app.after_request

和上个钩子类似,差别在于是请求完成时执行,它和之前钩子有点不同,必须传入一个参数来接收响应对象,并在最后return 这个参数,也就是返回响应内容。

场景:一般用于格式化响应结果,包括响应请求头,响应的格式等。


@app.after_request
def after_request(response):
response.headers['jidan'] = 'yaoyao'
return response

第六个钩子:@app.teardown_request

和第五个钩子功能类似,在响应销毁时,执行一个绑定的函数。做一些操作。

区别点在于:

 ●  after_request: 每一个请求之后绑定一个函数,如果请求没有异常。
 ●  teardown_request: 每一个请求之后绑定一个函数,即使遇到了异常。

场景:销毁DB连接等。


@app.teardown_request
def teardown_db(exception):
db = getattr(g, 'database', None)
if db is not None:
db.close()

第七个钩子:@app.teardown_appcontext

之前介绍的大部分是请求上下文的钩子,这个属于应用上下文的钩子。不管是否有异常,当APP上下文被移除之后执行的函数, 可以进行数据库的提交或者回滚。

场景:DB事务操作。


@app.teardown_appcontext
def teardown(cmd=None):
if cmd is None:
db.session.commit()
else:
db.session.rollback()
db.session.remove()


原文发布时间为:2018-09-20
本文作者:廖扬扬
本文来自云栖社区合作伙伴“ Python中文社区”,了解相关信息可以关注“ Python中文社区”。
相关文章
|
2月前
|
Python
Flask学习笔记(二):基于Flask框架上传图片到服务器端并原名保存
关于如何使用Flask框架上传图片到服务器端并以其原名保存的教程。
76 1
|
2月前
|
Python
Flask学习笔记(三):基于Flask框架上传特征值(相关数据)到服务器端并保存为txt文件
这篇博客文章是关于如何使用Flask框架上传特征值数据到服务器端,并将其保存为txt文件的教程。
31 0
Flask学习笔记(三):基于Flask框架上传特征值(相关数据)到服务器端并保存为txt文件
|
2月前
|
JSON 测试技术 数据库
Python的Flask框架
【10月更文挑战第4天】Python的Flask框架
|
2月前
|
存储 安全 数据库
Flask框架中,如何实现用户身份验证和会话管理?
【10月更文挑战第4天】Flask框架中,如何实现用户身份验证和会话管理?
|
2月前
|
存储 SQL 数据库
使用Python和Flask框架创建Web应用
【10月更文挑战第3天】使用Python和Flask框架创建Web应用
30 1
|
3月前
|
安全 数据安全/隐私保护 Python
基于Flask框架实现一个简易后台用户登录系统
基于Flask框架实现一个简易后台用户登录系统
|
3月前
|
人工智能 安全 数据安全/隐私保护
基于Flask框架实现一个简易后台用户登录系统
基于Flask框架实现一个简易后台用户登录系统
|
数据库 Python 关系型数据库
用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数
目录 目录 前文列表 视图函数 在 viewspy 文件中定义视图函数 定义右侧边栏的视图函数 为每一张数据表定义视图函数 前文列表 用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hello Wo...
1027 0
|
19天前
|
开发框架 前端开发 JavaScript
利用Python和Flask构建轻量级Web应用的实战指南
利用Python和Flask构建轻量级Web应用的实战指南
53 2
|
28天前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
29 2