如果有一天公司业务需求需要给所有视图函数添加功能,可以通过装饰器实现,但视图函数太多,有没有更好的办法呢?

before_request与after_request很简单,实现中功能同Django中中间件process_request与process_response的功能相同

1.前提,装饰器的弊端

我们现在有一个 Flask 程序其中有3个路由和视图函数,如下:

from flask import Flask

app = Flask(__name__)  # type:Flask

@app.route("/login")
def login():
return "Login" @app.route("/index")
def index():
return "Index" @app.route("/home")
def home():
return "Login" app.run("0.0.0.0", 5000)
from flask import Flask

app = Flask(__name__)  # type:Flask

@app.route("/login")
def login():
return "Login" @app.route("/index")
def index():
return "Index" @app.route("/home")
def home():
return "Login" app.run("0.0.0.0", 5000)

如果登陆了,就可以访问 index 和 home 页面,如果没登录就跳转到 login 登录

要怎么解决呢, session 对, 用 session 除了 Login 函数之外的所有函数里面全校验 session 是否登录了

太麻烦了,现在咱们只有3个函数,如果成百上千个怎么整啊

装饰器,对没错,装饰器是一个很好的方案,但是啊,我现在还是成败上千个函数,我要在每一个函数定义的时候加上@装饰器,还是很麻烦

2.before_request与after_request

2.1 before_request分析:

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/home")
def home():
return "Hello" @app.before_request
def be1():
print("be1")
return "出错了"
# return None @app.before_request
def be2():
print("be2")
return None @app.after_request
def af1(res):
print("af1")
return res @app.after_request
def af2(res):
print("af2")
return res if __name__ == '__main__':
app.run()

报错信息:

# Django中,如果当请求到达请求1的时候直接不符合条件返回,即return HttpResponse("Md1中断"),程序将把请求直接发给中间件1返回,然后依次返回到请求者,不再执行视图函数
# 在Flask中,如果当请求到达请求1的时候直接不符合条件返回,则会中最后一个@app.after_request中依次返回到请求者,不再执行视图函数,结果如下:
返回Md2中断的页面,后台打印如下:
be1
af2
af1

2.2 after_request分析:

@app.after_request报错则会依次返回结果  

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/home")
def home():
return "Hello" @app.before_request
def be1():
print("be1")
# return "出错了"
return None @app.before_request
def be2():
print("be2")
return None @app.after_request
def af1(res):
print("af1")
return res @app.after_request
def af2(res):
print("af2")
# return res
return "出错了" if __name__ == '__main__':
app.run()

报错信息:

# 返回结果be1
be2
af2
af1

3.before_request应用

@app.before_request 在请求(request)进入视图函数之前执行

@app.before_request 也是一个装饰器,他所装饰的函数,都会在请求进入视图函数之前执行

request.path 是来读取当前的url地址如果是 /login 就允许直接通过 return None 你可以理解成通过放行

校验session中是否有user 如果没有的话,证明没有登录,所以毫不留情的 redirect("/login") 跳转登录页面

还有一个要提的 @app.before_first_request 它与 @app.before_request 极为相似或者说是一模一样,只不过它只会被执行一次

from flask import Flask
from flask import request
from flask import redirect
from flask import session app = Flask(__name__) # type:Flask
app.secret_key = "DragonFire" @app.before_request
def is_login():   #白名单
if request.path == "/login":
return None
   #验证session
if not session.get("user"):
return redirect("/login")  return None @app.route("/login")
def login():
return "Login" @app.route("/index")
def index():
return "Index" @app.route("/home")
def home():
return "Login" app.run("0.0.0.0", 5000)

4.before_request应用

@app.after_request 在响应(response)返回客户端之前执行 , 结束视图函数之后

@app.after_request必须return返回上一层的参数environ,否则会报错

@app.after_request
def foot_log(environ):
if request.path != "/login":
print("有客人访问了",request.path)
return environ

5.用flask的实现一个简单的页面登录

基于before_request与after_request的验证登录

from flask import Flask,render_template,request,redirect,session
app = Flask(__name__,template_folder='templates')
app.secret_key = "sdsfdsgdfgdfgfh" @app.before_request
def process_request():
if request.path=="/login":
return None
if not session.get("user_info"):
return redirect("/login")
return None
@app.after_request
def process_response(response):
print(2222)
return response @app.route("/login",methods=["GET","POST"])
def login():
if request.method=="GET":
return render_template("login.html")
else:
# print(request.values) #这个里面什么都有,相当于body
username = request.form.get("username")
password = request.form.get("password")
if username=="annie" and password=="123":
session["user_info"] = username
# session.pop("user_info") #删除session
return redirect("/index")
else:
# return render_template("login.html",**{"msg":"用户名或密码错误"})
return render_template("login.html",msg="用户名或者密码错误") @app.route("/index",methods=["GET","POST"])
def index():
# if not session.get("user_info"):
# return redirect("/login")
return render_template("index.html") if __name__ == '__main__':
app.run(debug=True)

Flask中before_request与after_request使用的更多相关文章

  1. Flask之before_request、after_request

    1.@app.before_request在请求(request)|在视图函数   之前做出响应 解决所有问题 from flask import Flask from flask import re ...

  2. 第九篇 Flask的before_request和after_request

    Flask我们已经学习很多基础知识了,现在有一个问题 我们现在有一个 Flask 程序其中有3个路由和视图函数,如下: from flask import Flask app = Flask(__na ...

  3. Flask中的before_request装饰器和after_request装饰器以及WTForms组件

    一.before_request装饰器和after_request装饰器 我们现在有一个Flask程序其中有3个路由和视图函数 from flask import Flask app = Flask( ...

  4. Python框架学习之Flask中的视图及路由

    在前面一讲中我们学习如何创建一个简单的Flask项目,并做了一些简单的分析.接下来在这一节中就主要来讲讲Flask中最核心的内容之一:Werkzeug工具箱.Werkzeug是一个遵循WSGI协议的P ...

  5. flask中的g、add_url_rule、send_from_directory、static_url_path、static_folder的用法

    Flask中的g对象是个很好的东西,主要用于在一个请求的过程中共享数据.可以随意给g对象添加属性来保存数据,非常的方便,下面的代码是一个使用g对象的例子.下面的这个例子会使用random随机产生一个0 ...

  6. flask中Flask()和Blueprint() flask中的g、add_url_rule、send_from_directory、static_url_path、static_folder的用法

    1.Blueprint()在蓝本注册函数register_blueprint()中,第一个参数为所注册的蓝本名称.当我们在应用对象上注册一个蓝图时,需要指定一个url_prefix关键字 参数(这个参 ...

  7. Flask(2)- 装饰器的坑及解决办法、flask中的路由/实例化配置/对象配置/蓝图/特殊装饰器(中间件、重定义错误页面)

    一.装饰器的坑以及解决方法 1.使用装饰器装饰两个视图函数,代码如下 from flask import Flask, redirect, render_template, request, sess ...

  8. flask中的上下文_请求上下文和应用上下文

    前引 在了解flask上下文管理机制之前,先来一波必知必会的知识点. 面向对象双下方法 首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__.__getattr__系列.__get ...

  9. Flask 中的MTV架构之Views

    Flask 中的MTV架构之Views 1.MVC与MTV 1.1 MVC ​ M:model,模型,数据模型 ​ V:view,视图,负责数据展示 ​ C:controller,控制器,负责业务逻辑 ...

随机推荐

  1. kubectl-trace 基于bpftrace 的kubernetes 集群性能分析工具

    kubectl-trace 是一个kubectl 的插件,我们可以使用基于bpftrace 的编程能力,来分析系统的性能问题, 强大,灵活,后边安装试用下 参考架构 参考资料 https://gith ...

  2. [LeetCode] 21. Merge Two Sorted Lists 混合插入有序链表

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  3. TCP三次握手及四次断开,TCP有限状态机

    TCP 的连接建立 上图画出了 TCP 建立连接的过程.假定主机 A 是 TCP 客户端,B是服务端.最初两端的 TCP 进程都处于 CLOSED 状态.图中在主机下面的是 TCP进程所处的状态.A ...

  4. luoguP4213 【模板】杜教筛(Sum)杜教筛

    链接 luogu 思路 为了做hdu来学杜教筛. 杜教筛模板题. 卡常数,我加了register居然跑到不到800ms. 太深了. 代码 // luogu-judger-enable-o2 #incl ...

  5. icon发展史速览

    icon 发展史 img 多张图片占用多个请求,想办法减少请求,合并图片,image sprite background-position /* 使用background-position来定位图标 ...

  6. 基于paramiko将文件上传到服务器上

    通过安装使用paramiko模块,将本地文件上传到服务器上 import paramiko import datetime import os hostname = '服务器ip' username ...

  7. cocos: RenderTexture 合并精灵图片

    var render = new cc.RenderTexture(730, 450); //创建渲染纹理对象,并数字确定宽度 render.begin(); var sp1 = cc.Sprite. ...

  8. 【转】用VMware 8安装Ubuntu 12.04详细过程(图解)

    图解演示环境版本: 本机系统: WIN7 虚拟机:VMware Workstation 8 (英文版) 安装目标:Ubuntu Desktop 12.04 LTS  (请点击这里)先下载好iso镜像文 ...

  9. Prometheus 监控Docker服务器及Granfanna可视化

    Prometheus 监控Docker服务器及Granfanna可视化 cAdvisor(Container Advisor)用于收集正在运行的容器资源使用和性能信息. 使用Prometheus监控c ...

  10. 图解微信小程序---实现页面的跳转与返回操作

    图解微信小程序---实现页面的跳转与返回操作 代码笔记 操作步骤 第一步:在app.json配置文件中,创建跳转页面 第二步:编写首页跳转(注意跳转方式,和设置点击样式类名) 第三步:编写首页样式 第 ...