详解Django中间件的5种自定义方法


Posted in Python onJuly 26, 2018

Django中间件

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

中间件的执行流程

1、执行完所有的request方法 到达视图函数。

2、执行中间件的其他方法

3、经过所有response方法 返回客户端。

注意:如果在其中1个中间件里 request方法里 return了值,就会执行当前中间件的response方法,返回给用户 然后 报错。。不会再执行下一个中间件。

详解Django中间件的5种自定义方法

自定义中间件

1.在project下随便创建一个py文件

详解Django中间件的5种自定义方法

from django.utils.deprecation import MiddlewareMixin
class Middle1(MiddlewareMixin):
 def process_request(self,request):
  print("来了")
 def process_response(self, request,response):
  print('走了')

2、在setings文件中 注册这个 py文件

django项目的settings模块中,有一个 MIDDLEWARE_CLASSES变量,其中每一个元素就是一个中间件

详解Django中间件的5种自定义方法

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',
 'M1.Middle1',
]

执行结果

详解Django中间件的5种自定义方法

为啥报错了呢?

因为 自定义的中间件response方法没有return,交给下一个中间件,导致http请求中断了!!!

注意自定义的中间件request 方法不要return 因为返回值中间件不再往下执行,导致 http请求到达不了视图层,因为request在视图之前执行!

from django.utils.deprecation import MiddlewareMixin
class Middle1(MiddlewareMixin):
 def process_request(self,request):
  print("来了") #不用return Django内部自动帮我们传递
 def process_response(self, request,response):
  print('走了')
  return response #执行完了这个中间件一定要 传递给下一个中间件

详解Django中间件的5种自定义方法

中间件(类)中5种方法

中间件中可以定义5个方法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response

1、 process_view(self, request, callback, callback_args, callback_kwargs)方法介绍

(1)执行完所有中间件的request方法‘

(2)url匹配成功

(3)拿到 视图函数的名称、参数,(注意不执行) 再执行process_view()方法

(4)最后去执行视图函数

玩法1(常规)

from django.utils.deprecation import MiddlewareMixin


class M1(MiddlewareMixin):
 def process_request(self, request):
  print('M1.request') 

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M1.process_view")
  
 def process_response(self, request, response):
  print('M1.response')
  return response 



class M2(MiddlewareMixin):
 def process_request(self, request):
  print('M2.request') 

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M2.process_view")
 
 def process_response(self, request, response):
  print('M2.response')
  return response

执行结果

详解Django中间件的5种自定义方法

玩法2

既然 process_view 拿到视图函数的名称、参数,(不执行) 再执行process_view()方法,最后才去执行视图函数!

那可以在 执行process_view环节直接 把函数执行返回吗?

from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
 def process_request(self, request):
  print('M1.request')
     # callback视图函数名称 callback_args,callback_kwargs 视图函数执行所需的参数
 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M1.process_view")
  response=callback(request,*callback_args,**callback_kwargs)
  return response
 def process_response(self, request, response):
  print('M1.response')
  return response

class M2(MiddlewareMixin):
 def process_request(self, request):
  print('M2.request') 

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M2.process_view")
 def process_response(self, request, response):
  print('M2.response')
  return response

执行结果

详解Django中间件的5种自定义方法

结论:

如果process_view函数有返回值,跳转到最后一个中间件, 执行最后一个中间件的response方法,逐步返回。

和 process_request方法不一样哦! request方法在当前中间件的response方法返回。

2、process_exception(self, request, exception)方法

from django.utils.deprecation import MiddlewareMixin


class M1(MiddlewareMixin):
 def process_request(self, request):
  print('M1.request')
  
 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M1.process_view")

 def process_response(self, request, response):
  print('M1.response')
  return response

 def process_exception(self, request,exception):
  print('M1的process_exception')


class M2(MiddlewareMixin):
 def process_request(self, request):
  print('M2.request') 

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M2.process_view")

 def process_response(self, request, response):
  print('M2.response')
  return response

 def process_exception(self, request, exception):
  print('M2的process_exception')

我去 加了process_exception方法 咋啥也没执行呢?!!原来是process_exception默认不执行!!!

详解Django中间件的5种自定义方法

大爷的 原来process_exception方法在 视图函数执行出错的时候才会执行

M1.request
M2.request
M1.process_view
M2.process_view
执行index
M2的process_exception
M1的process_exception
Internal Server Error: /index/
Traceback (most recent call last):
 File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
 response = get_response(request)
 File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
 response = self.process_exception_by_middleware(e, request)
 File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
 response = wrapped_callback(request, *callback_args, **callback_kwargs)
 File "F:\untitled1\app01\views.py", line 7, in index
 int("ok")
ValueError: invalid literal for int() with base 10: 'ok'
M2.response
M1.response
[03/Jul/2017 16:43:59] "GET /index/ HTTP/1.1" 500 62663

1、执行完所有 request 方法

2、执行 所有 process_view方法

3、如果视图函数出错,执行process_exception(最终response,process_exception的return值)

如果process_exception 方法有了 返回值 就不再执行 其他中间件的 process_exception,直接执行response方法响应

4.执行所有response方法

5.最后返回process_exception的返回值

M1.request
M2.request
M1.process_view
M2.process_view
执行index
M2的process_exception (有了return值,直接执行response)
M2.response
M1.response

process_exception的应用

在视图函数执行出错时,返回错误信息。这样页面就不会 报错了!

class M1(MiddlewareMixin):
 def process_request(self, request):
  print('M1.request')

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M1.process_view")

 def process_response(self, request, response):
  print('M1.response')
  return response

 def process_exception(self, request,exception):
  print('M1的process_exception')


class M2(MiddlewareMixin):
 def process_request(self, request):
  print('M2.request')

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M2.process_view")

 def process_response(self, request, response):
  print('M2.response')
  return response

 def process_exception(self, request, exception):
  print('M2的process_exception')
  return HttpResponse('出错了兄弟!!!')

3、process_template_response()

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class M1(MiddlewareMixin):
 def process_request(self, request):
  print('M1.request')

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M1.process_view")

 def process_response(self, request, response):
  print('M1.response')
  return response


 def process_exception(self, request,exception):
  print('M1的process_exception')


class M2(MiddlewareMixin):
 def process_request(self, request):
  print('M2.request')

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M2.process_view")

 def process_response(self, request, response):
  print('M2.response')
  return response

 def process_exception(self, request, exception):
  print('M2的process_exception')

 def process_template_response(self,request,response):
  print('M2process_template_response')
  return response

process_template_response()默认不执行

详解Django中间件的5种自定义方法

rocess_template_response()特性

只有在视图函数的返回对象中有render方法才会执行!

并把对象的render方法的返回值返回给用户(注意不返回视图函数的return的结果了,而是返回视图函数 return值(对象)的render方法)

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse


class M1(MiddlewareMixin):
 def process_request(self, request):
  print('M1.request')

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M1.process_view")

 def process_response(self, request, response):
  print('M1.response')
  return response


 def process_exception(self, request,exception):
  print('M1的process_exception')


class M2(MiddlewareMixin):
 def process_request(self, request):
  print('M2.request')

 def process_view(self, request,callback,callback_args,callback_kwargs ):
  print("M2.process_view")

 def process_response(self, request, response):
  print('M2.response')
  return response

 def process_exception(self, request, exception):
  print('M2的process_exception')

 def process_template_response(self,request,response): #如果视图函数中的返回值 中有render方法,才会执行 process_template_response
  print('M2process_template_response')
  return response

视图函数

from django.shortcuts import render,HttpResponse

# Create your views here.
class Foo():
 def __init__(self,requ):
  self.req=requ
 def render(self):
  return HttpResponse('OKKKK')

def index(request):
 print("执行index")
 obj=Foo(request)
 return obj

执行结果

详解Django中间件的5种自定义方法

应用:

既然process_template_respnse,不返回视图函数的return的结果,而是返回视图函数 return值(对象)的render方法;(多加了一个环节)

就可以在 这个视图函数返回对象的 render方法里,做返回值的二次加工了!多加工几个,视图函数就可以随便使用了!

(好比 喷雾器有了多个喷头,换不同的喷头喷出不同水,返回值就可以也组件化了)

from django.shortcuts import render,HttpResponse

# Create your views here.
class Dict(): #对视图函数返回值做二次封装 !!
 def __init__(self,requ,msg):
  self.req=requ 
  self.msg=msg
 def render(self):
  a=self.msg #在render方法里面 把视图函数的 返回值 制作成字典 、列表等。。。 
     # 如果新增了其他 一个视图函数直接,return对象 即可!不用每个视图函数都写 制作字典 列表 拼接的逻辑了
  return HttpResponse(a) #

def index(request):
 print("执行index")
 obj=Dict(request,"vv")
 return obj

中间件应用场景

由于中间件工作在 视图函数执行前、执行后(像不像所有视图函数的装饰器!)适合所有的请求/一部分请求做批量处理

1、做IP限制

放在 中间件类的列表中,阻止某些IP访问了;

2、URL访问过滤

如果用户访问的是login视图(放过)

如果访问其他视图(需要检测是不是有session已经有了放行,没有返回login),这样就省得在 多个视图函数上写装饰器了!

3、缓存(还记得CDN吗?)

客户端请求来了,中间件去缓存看看有没有数据,有直接返回给用户,没有再去逻辑层 执行视图函数

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用logging模块代替print(logging简明指南)
Jul 09 Python
python调用java模块SmartXLS和jpype修改excel文件的方法
Apr 28 Python
详解Python的Django框架中的通用视图
May 04 Python
对python3 中方法各种参数和返回值详解
Dec 15 Python
python执行精确的小数计算方法
Jan 21 Python
详解Python logging调用Logger.info方法的处理过程
Feb 12 Python
NumPy 基本切片和索引的具体使用方法
Apr 24 Python
为什么相对PHP黑python的更少
Jun 21 Python
Python趣味入门教程之循环语句while
Aug 26 Python
Python基础之函数嵌套知识总结
May 23 Python
python开发的自动化运维工具ansible详解
Aug 07 Python
使用Python开发贪吃蛇游戏 SnakeGame
Apr 30 Python
python opencv实现切变换 不裁减图片
Jul 26 #Python
Flask之flask-script模块使用
Jul 26 #Python
对tf.reduce_sum tensorflow维度上的操作详解
Jul 26 #Python
TensorFlow用expand_dim()来增加维度的方法
Jul 26 #Python
Python迭代器与生成器基本用法分析
Jul 26 #Python
Python实现矩阵相乘的三种方法小结
Jul 26 #Python
python实现泊松图像融合
Jul 26 #Python
You might like
php 带逗号千位符数字的处理方法
2012/01/10 PHP
php curl_init函数用法
2014/01/31 PHP
php检测数组长度函数sizeof与count用法
2014/11/17 PHP
讲解WordPress开发中一些常用的debug技巧
2015/12/18 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
php+ajax简单实现全选删除的方法
2016/12/06 PHP
JQuery入门——移除绑定事件unbind方法概述及应用
2013/02/05 Javascript
JavaScript 垃圾回收机制分析
2013/10/10 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
JavaScript中的undefined学习总结
2013/11/30 Javascript
ext combobox动态加载数据库数据(附前后台)
2014/06/17 Javascript
Javascript与jQuery方法的隐藏与显示
2015/01/19 Javascript
JavaScript通过setTimeout实时显示当前时间的方法
2015/04/16 Javascript
jQuery中cookie插件用法实例分析
2015/12/04 Javascript
Ionic3 UI组件之Gallery Modal详解
2017/06/07 Javascript
vue中实现在外部调用methods的方法(推荐)
2018/02/08 Javascript
elementUi vue el-radio 监听选中变化的实例代码
2019/06/28 Javascript
微信小程序防止多次点击跳转(函数节流)
2019/09/19 Javascript
[18:32]DOTA2 HEROS教学视频教你分分钟做大人-谜团
2014/06/12 DOTA
Python实现合并字典的方法
2015/07/07 Python
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
Numpy中转置transpose、T和swapaxes的实例讲解
2018/04/17 Python
对pandas通过索引提取dataframe的行方法详解
2019/02/01 Python
解决windows下python3使用multiprocessing.Pool出现的问题
2020/04/08 Python
Python参数传递对象的引用原理解析
2020/05/22 Python
15款Python编辑器的优缺点,别再问我“选什么编辑器”啦
2020/10/19 Python
钳工实习自我鉴定
2013/09/19 职场文书
最新离婚协议书范本
2014/08/19 职场文书
2014公安机关纪律作风整顿思想汇报
2014/09/13 职场文书
2014党委书记四风对照检查材料思想汇报
2014/09/21 职场文书
党员作风建设整改方案
2014/10/27 职场文书
2015年幼儿园中班开学寄语
2015/05/27 职场文书
2015年“我们的节日·中秋节”活动总结
2015/07/30 职场文书
会议室使用管理制度
2015/08/06 职场文书
MySQL令人大跌眼镜的隐式转换
2021/08/23 MySQL
Js类的构建与继承案例详解
2021/09/15 Javascript