一、概念

1、什么是中间件?

  官方解释:中间件是用来处理Django的请求和响应的框架级别的钩子。基于全局范围产生影响。

  平民解释:中间件是帮助我们在视图函数执行前和执行后做的操作。它本质上就是一个自定义类,类中定义了几个方法,Django框架会在处理请求的特定的时间去执行这些方法。其余request请求,终于response请求。

2、中间件在Django项目中Settings.py文件的配置

  

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配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个一个的类,也就是一个一个的中间件。

3、自定义中间件

  1、中间件可以定义五个方法,分别是:

    1、process_request(self,request)        处理请求的方法

    2、process_view(self,request,view_func,view_args,view_kwargs)        处理视图的方法

    3、process_template_response(self,request,response)  处理模板的方法

    4、process_exception(self,request,exception)  处理异常的方法

    5、process_response(self,request,response)  处理响应的方法

  以上方法的返回值可以使None,或者是HttpResponse对象,如果是None,就按照自定义的中间件的方法继续向下执行,直到process_response方法执行结束,如果是HttpResponse对象,就直接将这个对象返回给用户。

二、五种自定义中间件

  1、process_request

  自定义一个中间件的示例

    1、在APP下创建一个py文件,在py文件中定义中间件

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):

    def process_request(self, request):            #  process_request方法
print("MD1里面的 process_request")      # 此时没有返回值 依次向下执行 def process_response(self, request, response): # process_response方法
print("MD1里面的 process_response")
return response
class MD2(MiddlewareMixin):

    def process_request(self, request):            #  process_request方法
print("MD2里面的 process_request")      # 此时没有返回值 依次向下执行 def process_response(self, request, response): # process_response方法
print("MD2里面的 process_response")
return response

    2、需要在setting.py中的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',
'middlewares.MD1', # 自定义中间件MD1
'middlewares.MD2' # 自定义中间件MD2
]

    3、当浏览器发送了请求之后,Django服务器响应请求,返回给浏览器。此时终端打印出如下内容:

MD1里面的 process_request
MD2里面的 process_request
app01 中的 index视图

    4、如果把MD1he MD2在setting.py中的顺序调换一下,打印内容就是如下:

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index视图

    因此,process_request的执行顺序是按照注册顺序执行的。且是在视图函数执行前执行的。

    5、总结:

      1、中间件的process_request方法是在执行视图函数之前执行的。

      2、当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,从上到下依次执行。

      3、不同中间件之间传递的request都是同一个对象。从请求开始到响应结束,request都是同一个对象。

      4、如果内部有返回 HttpResponse对象,则不去执行视图函数,而是直接跳过所有的中间环节,执行process_response方法,以及其前边的方法。

  2、process_response

    1、示例

  

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):     # 中间件MD1

    def process_request(self, request):           # process_response方法
print("MD1里面的 process_request") def process_response(self, request, response):
print("MD1里面的 process_response")
return response class MD2(MiddlewareMixin): # 中间件MD2
def process_request(self, request):
print("MD2里面的 process_request") def process_response(self, request, response):
print("MD2里面的 process_response")
return response # 每个类都是一个中间件

    2、process_response(self,request,response)有两个参数,request就是一个请求对象,response是视图函数放给的HttpResponse对象。该方法的返回值,也就是直接在中间件中写的返回值也必须是HttpResponse对象。

    3、访问视图函数,即匹配URL之后,执行视图函数。打印如下内容

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index视图
MD1里面的 process_response
MD2里面的 process_response

    如图所示:process_response方法是在视图函数执行之后,执行的。并且当有多个process_response方法时,按照 注册顺序的倒叙执行。

  3、process_view

    1、处理视图的函数

      process_view(self,request,view_func,view_args,view_kwargs)

      该方法有四个参数

      1.request是HttpRequest对象

      2.view_func 是Django使用的视图函数。(它是实际的函数对象,而不是一个单纯的函数名字)。

      3.view_args是传递给视图函数的位置参数的元祖

      4.view_kwargs是传递给视图函数的关键字参数的字典

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

      他可以返回None或HttpResponse对象。如果返回None,继续向下执行,如果返回HttpResponse对象,将不再继续向下执行其他中间件中的process_view方法,而是直接执行process_response方法。

    3、示例

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):

    def process_request(self, request):        # resquest 方法
print("MD1里面的 process_request") def process_response(self, request, response): # response 方法
print("MD1里面的 process_response")
return response def process_view(self, request, view_func, view_args, view_kwargs): # view方法
print("-" * 80)
print("MD1 中的process_view")
print(view_func, view_func.__name__) 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("-" * 80)
print("MD2 中的process_view")
print(view_func, view_func.__name__)

    输出结果

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001DE68317488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001DE68317488> index
app01 中的 index视图
MD1里面的 process_response
MD2里面的 process_response

    由图可知:process_view方法是在process_request之后,视图函数之前,并且按照注册顺序的正序执行。

  4、process_exception

    1、处理异常的方法

    2、参数

    process_exception(self,request,exception)

      1、HttpRequest对象

      2、视图函数异常时产生的Exception对象

    3、只有当视图函数异常时才会执行。如果返回只是None,就继续向下执行,如果返回值是一个HttpResponse对象,则不再继续向下执行其他的中间件的process_exception方法,而是直接执行process_response方法。且如果有多个中间件的时候,按照注册顺序的倒叙执行。

    4、示例

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_response")
return response def process_view(self, request, view_func, view_args, view_kwargs):
print("-" * 80)
print("MD1 中的process_view")
print(view_func, view_func.__name__) def process_exception(self, request, exception):
print(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("-" * 80)
print("MD2 中的process_view")
print(view_func, view_func.__name__) def process_exception(self, request, exception):
print(exception)
print("MD2 中的process_exception")

    打印结果

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x0000022C09727488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x0000022C09727488> index
app01 中的 index视图
呵呵
MD1 中的process_exception
MD1里面的 process_response
MD2里面的 process_response

    注意,这里没有执行MD2中的process_exception方法,因为MD1中的process_exception方法已经返回了响应对象。

   5、process_template_response

    1、参数:

        process_template_response(self,request,response)

        一个是HttpRequest对象,response是一个TemplateResponse对象。

    2、process_template_response是在视图函数执行完成之后立即执行的,但是前提条件是,视图函数返回的对象有一个render()方法

    3、示例

class MD1(MiddlewareMixin):

    def process_request(self, request):
print("MD1里面的 process_request") def process_response(self, request, response):
print("MD1里面的 process_response")
return response def process_view(self, request, view_func, view_args, view_kwargs):
print("-" * 80)
print("MD1 中的process_view")
print(view_func, view_func.__name__) def process_exception(self, request, exception):
print(exception)
print("MD1 中的process_exception")
return HttpResponse(str(exception)) def process_template_response(self, request, response):
print("MD1 中的process_template_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 def process_view(self, request, view_func, view_args, view_kwargs):
print("-" * 80)
print("MD2 中的process_view")
print(view_func, view_func.__name__) def process_exception(self, request, exception):
print(exception)
print("MD2 中的process_exception") def process_template_response(self, request, response):
print("MD2 中的process_template_response")
return response

     views.py中

def index(request):
print("app01 中的 index视图") def render():
print("in index/render")
return HttpResponse("O98K")
rep = HttpResponse("OK")
rep.render = render
return rep

    4、输出结果

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001C111B97488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001C111B97488> index
app01 中的 index视图
MD1 中的process_template_response
MD2 中的process_template_response
in index/render
MD1里面的 process_response
MD2里面的 process_response

    试图执行完成之后,立即执行process_template_response方法,顺序是倒叙执行。先执行MD1,再执行MD2,接着执行视图函数的HttpResponse对象的render方法,返回一个新的HttpResponse对象,接着执行中间件的process_response方法。

Django 之 中间件的更多相关文章

  1. 自定义Django的中间件

    分析Django的生命周期,我们知道所有的http请求都要经过Django的中间件. 假如现在有一个需求,所有到达服务端的url请求都在系统中记录一条日志,该怎么做呢? Django的中间件的简介 D ...

  2. python/ Django之中间件

    python/ Django之中间件 一.中间件 中间件共分为: (1)process_request(self,request) (2)process_view(self, request, cal ...

  3. Django组件-中间件

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

  4. 细说Django的中间件

    分析Django的生命周期,我们知道所有的http请求都要经过Django的中间件. 假如现在有一个需求,所有到达服务端的url请求都在系统中记录一条日志,该怎么做呢? Django的中间件的简介 D ...

  5. csrf 跨站请求伪造相关以及django的中间件

    django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware来完成. 1.django中常用的中间件? - proces ...

  6. python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)

    一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...

  7. django 自定义中间件 middleware

    Django 中间件 Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出.中间件的设计为开发者提供了一种无侵入式的开发方式,增强 ...

  8. day 52 Django 的中间件加载顺序

    前情提要: django的中间键的作用是进行加载 可以通过中间键进行辅助操作 1.中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局 ...

  9. django框架--中间件系统

    目录 零.参考 一.中间件的基本理解 二.中间件的系统定位 三.中间件的配置 四.中间件的执行流程 五.中间件与装饰器之间的思考 六.中间件的应用场景 七.内置中间件 八.总结 零.参考 https: ...

  10. 浅谈Django的中间件与Python的装饰器

    浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...

随机推荐

  1. 关于JS正则表达式

    去除所有P标签 content=content.replace(/<([\/]?)(p)((:?\s*)(:?[^>]*)(:?\s*))>/g, ''); 将所有的  1.     ...

  2. iOS学习笔记06-手势识别

    一.UIGestureRecognizer简单介绍 我们已经学习了触摸事件处理,但触摸事件处理起来很麻烦,每个触摸事件处理都需要实现3个touches方法,比较繁琐,实际上我们可以使用更加简单的触摸事 ...

  3. 【Luogu】P3708Koishi的数字游戏(数论)

    题目链接 考虑f(i)=i%1+i%2+i%3+.....+i%n f(i+1)=(i+1)%1+(i+1)%2+......+(i+1)%n 其中不是i+1的因数的部分在f(i+1)的地方都加了1. ...

  4. Lucas 卢卡斯定理

    Lucas: 卢卡斯定理说白了只有一条性质 $$ C^n_m \equiv C^{n/p}_{m/p} \times C^{n \bmod p}_{m \bmod p} \ (mod \ \ p) $ ...

  5. 连接mysql报错 : The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone...

    time zone 时区错误 DBEAVER连接MySQL运行报错The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or repres ...

  6. java实现简单的算法

    排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有可以分为以下几类: (1).插 ...

  7. MACBOOK 忘记密码

    如果没有系统安装盘,可以采用下面的几种方法:首先,启动机器,启动时按住Apple和S键,以单用户模式(single user mode)进入系统.输入:mount -uv / 然后回车.接下来可以采用 ...

  8. perf stat 输出解读

    http://zhengheng.me/2015/11/12/perf-stat/ http://zhengheng.me/2015/08/30/perf-tools/

  9. python 工具 FFT变换

    import numpy as npimport pylabwave_data =np.fromfile("C:\\Users\\Administrator\\Desktop\\bins\\ ...

  10. Ghost本地安装highlight.js使代码高亮

    对于程序猿写博客来说,这代码高亮是起码的要求.可是Ghost本身没有支持高亮代码. 可是能够通过扩展来实现,它就是highlight.js--附官方站点,看了下首页介绍,真的非常强大,如今说说怎么进行 ...