一 中间件基本介绍

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

Django的中间件的定义:

中间件是 Django 用来处理请求和响应的钩子框架。它是一个轻量级的、底层级的“插件”系统,用于全局性地控制Django 的输入或输出,可以理解为内置的app或者小框架。

如果想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

Django默认的Middleware:

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。cnfs也是一个中间件

二 自建一个中间件

2.1 process_request中间件

root@darren-virtual-machine:~/PycharmProjects/cookie_seesion# vim cookie/Middlewares.py

from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法") class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法")

注册中间件

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'cookie.Middlewares.MD1',
'cookie.Middlewares.MD2',
]

访问http://127.0.0.1:8000/cookie/login/,调试结果如下

MD1下的process_request 方法
MD2下的process_request 方法

这里的结果是按照注册顺序执行的

配置views

from django.shortcuts import render,redirect,HttpResponse

# Create your views here.
def login_required(func):
def inner(request,*args,**kwargs):
if not request.COOKIES.get("is_login"):
return redirect("/cookie/login/")
rep = func(request,*args,**kwargs)
return rep
return inner @login_required
def index(request):
# if not request.COOKIES.get("is_login"):
# return redirect("/cookie/login/")
print("index 视图")
return render(request,"index.html")
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
rep = redirect("/cookie/index/")
rep.set_cookie("is_login",True)
return rep
else:
return redirect("/cookie/login/")
def loginout(request):
rep = redirect("/cookie/login/")
rep.delete_cookie("is_login")
return rep @login_required
def order(request):
# if not request.COOKIES.get("is_login"):
# return redirect("/cookie/login/")
return HttpResponse("oreder success")

登录查看结果

MD1下的process_request 方法
MD2下的process_request 方法
index 视图

process_request是在view之后输出的

2.2 process_reponse中间件

root@darren-virtual-machine:~/PycharmProjects/cookie_seesion# vim cookie/Middlewares.py

访问报错

这是因为在request,必须有回应

输出结果

MD1下的process_request 方法
MD2下的process_request 方法
MD2下的process_reponse 方法
MD1下的process_reponse 方法

先执行response的MD2

添加响应

结果

MD1下的process_request 方法
MD2下的process_request 方法
index 视图
MD2下的process_reponse 方法
MD1下的process_reponse 方法

在return response返回的对象就是

验证:

views文件

from django.shortcuts import render,redirect,HttpResponse

# Create your views here.
def login_required(func):
def inner(request,*args,**kwargs):
if not request.COOKIES.get("is_login"):
return redirect("/cookie/login/")
rep = func(request,*args,**kwargs)
return rep
return inner @login_required
def index(request):
# if not request.COOKIES.get("is_login"):
# return redirect("/cookie/login/")
print("index 视图")
rep = render(request,"index.html")
print(id(rep))
return rep
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
rep = redirect("/cookie/index/")
rep.set_cookie("is_login",True)
return rep
else:
return redirect("/cookie/login/")
def loginout(request):
rep = redirect("/cookie/login/")
rep.delete_cookie("is_login")
return rep @login_required
def order(request):
# if not request.COOKIES.get("is_login"):
# return redirect("/cookie/login/")
return HttpResponse("oreder success")

中间件

root@darren-virtual-machine:~/PycharmProjects/cookie_seesion# vim cookie/Middlewares.py

from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
def process_response(self,request,response):
print("MD1下的process_reponse 方法")
print(id(response))
return response class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法")
def process_response(self,request,response):
print("MD2下的process_reponse 方法")
return response

访问结果,是一致的

MD1下的process_request 方法
MD2下的process_request 方法
index 视图
139857132829104
MD2下的process_reponse 方法
MD1下的process_reponse 方法
139857132829104

所以上面错误的原因,是因为resonse没有返回值,则默认的返回值为null,导致报错,返回response后,就是返回render(request,"index.html")

在request添加返回值

root@darren-virtual-machine:~/PycharmProjects/cookie_seesion# vim cookie/Middlewares.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
return HttpResponse("Hello 我来了")
def process_response(self,request,response):
print("MD1下的process_response 方法")
print(id(response))
return response class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法")
def process_response(self,request,response):
print("MD2下的process_response 方法")
return response

访问http://127.0.0.1:8000/cookie/login/,没有到view层

输出

MD1下的process_request 方法
MD1下的process_response 方法
140023033668160

如图,当reques的中间件中,有返回值,就会直接返回,不会走到下面的reques和视图层,生命请求周期如下:

2.3 process_view方法

该方法有四个参数

  • request是HttpRequest对象。
  • view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)
  • view_args是将传递给视图的位置参数的列表.
  • view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。

  Django会在调用视图函数之前调用process_view方法。

  它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。

添加process_view

root@darren-virtual-machine:~/PycharmProjects/cookie_seesion# vim cookie/Middlewares.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
#return HttpResponse("Hello 我来了")
def process_response(self,request,response):
print("MD1下的process_response 方法")
#print(id(response))
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD1下的process_view 方法") class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法")
def process_response(self,request,response):
print("MD2下的process_response 方法")
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD2下的process_view 方法")

输出结果

MD1下的process_request 方法
MD2下的process_request 方法
MD1下的process_view 方法
MD2下的process_view 方法
index 视图
MD2下的process_response 方法
MD1下的process_response 方法

process_view方法是在process_request之后,视图函数之前执行的,执行顺序按照MIDDLEWARE中的注册顺序从前到后顺序执行。

在MD1下的porcess_view返回一个返回值

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
#return HttpResponse("Hello 我来了")
def process_response(self,request,response):
print("MD1下的process_response 方法")
#print(id(response))
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD1下的process_view 方法")
return view_func(request)
class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法")
def process_response(self,request,response):
print("MD2下的process_response 方法")
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD2下的process_view 方法")

执行结果

MD1下的process_request 方法
MD2下的process_request 方法
MD1下的process_view 方法
index 视图
MD2下的process_response 方法
MD1下的process_response 方法

2.4 process_exception

语法:

process_exception(self, request, exception)

该方法两个参数:

  • HttpRequest对象
  • exception是视图函数异常产生的Exception对象。

  这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

添加process_exception

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
#return HttpResponse("Hello 我来了") def process_response(self,request,response):
print("MD1下的process_response 方法")
#print(id(response))
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD1下的process_view 方法")
#return view_func(request) def process_exception(self,request,exception):
print("MD1下的process_exception 方法") class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法") def process_response(self,request,response):
print("MD2下的process_response 方法")
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD2下的process_view 方法") def process_expection(self,request,exception):
print("MD2下的process_exception 方法")

访问结果

MD1下的process_request 方法
MD2下的process_request 方法
MD1下的process_view 方法
MD2下的process_view 方法
index 视图
MD2下的process_response 方法
MD1下的process_response 方法

并没有exception,是因为需要view异常才会触发

制造views异常

from django.shortcuts import render,redirect,HttpResponse

# Create your views here.
def login_required(func):
def inner(request,*args,**kwargs):
if not request.COOKIES.get("is_login"):
return redirect("/cookie/login/")
rep = func(request,*args,**kwargs)
return rep
return inner @login_required
def index(request):
# if not request.COOKIES.get("is_login"):
# return redirect("/cookie/login/")
print("index 视图")
int("aaa")
rep = render(request,"index.html")
#print(id(rep))
return rep
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
username = request.POST.get("username")
password = request.POST.get("password")
if username == "joy" and password == "123456":
rep = redirect("/cookie/index/")
rep.set_cookie("is_login",True)
return rep
else:
return redirect("/cookie/login/")
def loginout(request):
rep = redirect("/cookie/login/")
rep.delete_cookie("is_login")
return rep @login_required
def order(request):
# if not request.COOKIES.get("is_login"):
# return redirect("/cookie/login/")
return HttpResponse("oreder success")

访问http://127.0.0.1:8000/cookie/index/

输出结果

MD1下的process_request 方法
MD2下的process_request 方法
MD1下的process_view 方法
MD2下的process_view 方法
index 视图
MD2下的process_exception 方法
MD1下的process_exception 方法
MD2下的process_response 方法
MD1下的process_response 方法 

在exception添加错误返回

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
#return HttpResponse("Hello 我来了") def process_response(self,request,response):
print("MD1下的process_response 方法")
#print(id(response))
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD1下的process_view 方法")
#return view_func(request) def process_exception(self,request,exception):
print("MD1下的process_exception 方法")
return HttpResponse(exception) class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法") def process_response(self,request,response):
print("MD2下的process_response 方法")
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD2下的process_view 方法") def process_exception(self,request,exception):
print("MD2下的process_exception 方法")

访问结果没有报错

输出

MD1下的process_request 方法
MD2下的process_request 方法
MD1下的process_view 方法
MD2下的process_view 方法
index 视图
MD2下的process_exception 方法
MD1下的process_exception 方法
MD2下的process_response 方法
MD1下的process_response 方法

在MD2返回

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print("MD1下的process_request 方法")
#return HttpResponse("Hello 我来了") def process_response(self,request,response):
print("MD1下的process_response 方法")
#print(id(response))
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD1下的process_view 方法")
#return view_func(request) def process_exception(self,request,exception):
print("MD1下的process_exception 方法") class MD2(MiddlewareMixin):
def process_request(self, request):
print("MD2下的process_request 方法") def process_response(self,request,response):
print("MD2下的process_response 方法")
return response def process_view(self,request,view_func,view_args,view_kwargs):
print("MD2下的process_view 方法") def process_exception(self,request,exception):
print("MD2下的process_exception 方法")
return HttpResponse(exception)

访问结果

MD1下的process_request 方法
MD2下的process_request 方法
MD1下的process_view 方法
MD2下的process_view 方法
index 视图
MD2下的process_exception 方法
MD2下的process_response 方法
MD1下的process_response 方法

没有MD1的exception,已经跳过,流程如下

绿色为正常流程,红色是则MD2添加return返回

060.Python组件-中间件的更多相关文章

  1. PySC2是DeepMind的“星际争霸II学习环境”(SC2LE)的Python组件

    PySC2是DeepMind的"星际争霸II学习环境"(SC2LE)的Python组件. 它暴露了暴雪娱乐公司的星际争霸II机器学习API作为Python RL环境. 这是Deep ...

  2. [转]页游开发中的 Python 组件与模式Presentation Transcript

    转: 页游开发中的 Python 组件与模式Presentation Transcript 1. 页游开发中的 Python 组件与模式 赖勇浩( http://laiyonghao.com ) 20 ...

  3. 如何在windows下成功的编译和安装python组件hyperscan

    摘要:hyperscan 是英特尔推出的一款高性能正则表达式引擎,一次接口调用可以实现多条规则与多个对象之间的匹配,可以支持多种匹配模式,块模式和流模式,它是以PCRE为原型开发,并以BSD许可证开源 ...

  4. Python Django 中间件

    在http请求 到达视图函数之前   和视图函数return之后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 中间件的执行流程 1.执行完所有的request方法 到达视图函数. ...

  5. Django:(7)auth用户认证组件 & 中间件

    用户认证组件 用户认证组件: 功能:用session记录登陆验证状态 前提:用户表:django自带的auth_user 创建超级用户的命令: python manage.py createsuper ...

  6. Django组件-中间件

    1.中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影 ...

  7. python Django 中间件介绍

    我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下面的MIDDLEWARE配置项,django默认自带的一些中间件: MIDDLEWARE = [ ' ...

  8. Django之组件--中间件

    中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响到性能 自定义中间 ...

  9. Django 组件-中间件

    中间件 中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好 ...

随机推荐

  1. KubeEdge EdgeMesh设计原理

    EdgeMesh主要用来做边缘侧微服务的互访. ServiceMesh service mesh是一个服务网格的概念.在传统的架构里面都是通过像Dubbo来进行服务治理,服务治理的程序和我们应用程序强 ...

  2. JavaScript深入理解-Set、Map、WeakSet和WeakMap

    Set Set 对象允许储存任何类型的唯一值,无论是原始值或者是对象引用 本质:构造函数,用来生成 Set 数据结构 描述 Set 对象是值的集合,你可以按照插入的顺序迭代它的元素.Set 中的元素只 ...

  3. Linux执行.sh文件,提示No such file or directory的问题

    问题描述 在window平台下,写好shell脚本文件,迁移到linux平台,赋过可执行权限,执行该sh文件,却提示NO such file or directory 解决方案 难道是文件格式兼容性问 ...

  4. 某大佬的TODOLIST

    回文串 manacher(完成时间:2018.12.10)回文串计数最长双回文串(完成时间:2018.12.10) 扫描线 棋盘制作巨大的牛棚玉蟾宫某个blog 汉诺塔相关 新汉诺塔SHOI 博弈论 ...

  5. mac系统 PHP Nginx环境变量修改

    场景:php默认的环境变量不是我们实际工作中想要的 执行命令:which php 查看默认的php指向的目录 :  /usr/bin/php 修改· ~/.bash_profile 文件 添加php环 ...

  6. 【工具库】Java实体映射工具MapStruct

    一.什么是MapStruct? MapStruct是用于代码中JavaBean对象之间的转换,例如DO转换为DTO,DTO转换为VO,或Entity转换为VO等场景,虽然Spring库和 Apache ...

  7. Python 使用xlsxwriter绘制Excel表格

    最近在统计资产,正好看到了xlsxwriter这个表格生成模块,借此机会,熟悉一下,写点有趣的小案例,一开始想使用C++ QT图形化开发一套自动化运维平台,但后来发现不仅消耗时间而且需要解决QT Qs ...

  8. Python字体颜色设置

    Python字体颜色设置 平时学习工作中,我们经常会接触到一些大佬写的Python工具,运行起来总会显示出五颜六色的字体,比如红色代表Error , 黄色代表Warning , 绿色代表Success ...

  9. hdu3585 二分最大团(dp优化)

    题意       给你一些点( <= 50),让你找到k个点,使得他们之间的最小距离最大. 思路:       求最小的最大,我们可以直接二分去枚举距离,但是要注意,不要去二分double找距离 ...

  10. adbi学习:so hook实现机制

    本篇我们来看看adbi的实现原理,其实里面的知识点前面差不多都有涉及了,没多少新知识.adbi利用hijack程序将libexample.so注入到指定的进程中,并且在进程中加载libexample. ...