Django 1.6 中间件

本篇译自 django 官方文档:https://docs.djangoproject.com/en/1.6/topics/http/middleware/

 

中间件是嵌入 django 的 request/response 处理过程的一套钩子框架。它是一个轻量级的底层嵌入系统,可以对 django 的输入输出做整体的修改。

 

激活中间件

将需要激活的中间件添加到项目 settings 文件内即可,初始状态下他是这个样子的:


   
MIDDLEWARE_CLASSES = ( ' 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_CLASS 的元素是有顺序的,因为中间件之间可能存在依赖关系。

 

钩子和应用顺序

中间件具体是由包装了一些特定方法(钩子)的类来实现的。

在 request 阶段,调用 view 之前,django 依 MIDDLEWARE_CLASSES 定义的顺序依次套用各个中间件,但其中只有两个钩子会被调用:

  • process_request()
  • process_view()

在 response 阶段,调用 view 之后,django 以 request 阶段的倒序来套用各个中间件,其中会被调用的有三种钩子:

  • process_exception() (只有 view 引发异常的时候)
  • process_template_response (仅限 template response)
  • process_response()

整个应用过程可以看做是包裹着 view 内核的一层层洋葱皮,每个中间件就是一层。

middleware.svg

 

process_request(request)

本方法会对每一个 request 调用,在 django 决定使用哪个 view 之前。

本方法只能返回两种值:None 或者一个 HttpResponse 对象。当返回 None 的时候,django 会继续套用其他中间件和 view;当返回 HttpResponse 对象的时候,django 会直接跳过其他 request 阶段的中间件、process_exception() 和 view,仅调用 response 阶段中间件然后返回。

 

process_view(request,view_func,view_args,view_kwargs)

本方法调用于 view 之前。(view_func 参数应当是一个可调用对象,而不是函数名的字符串。另,后面的参数中都不包含 request 对象)

返回值同上

 

注意:在 process_request() 和 process_view() 中不应当访问 request.POST 和 request.REQUEST

 

process_template_response(request,response)

本方法调用于 view 刚刚完成之后。response 参数应当是一个由 view 或中间件返回的 TemplateResponse 对象(或等价对象),这一点可以通过 response 实例中是否含有 .render() 方法鉴别。

本方法必须返回一个实现了 render() 方法的 response 对象。本方法可以通过修改 response.template_name 和 response.context_data 属性来修改原本的 response 并返回,也可以 自建一个新的 TemplateResponse 对象(或等价对象)。

你不需要显式地去渲染 response,这个过程会在本方法调用的最后被自动执行。

 

process_response(request,response)

本方法调用于每一个 response 被返回给客户端之前。其中 response 参数是一个由 view 或中间件返回的 HttpResponse 对象,或 StreamingHttpResponse 对象。

本方法也必然的只能返回这两种对象。被返回的对象同样可以是从参数 response 修改而来或自建的新对象。

和 process_request() , process_view() 不同,本方法总是会被调用,即使他们处于同一中间件内。前面提到过,request 阶段中间件如果返回了 response 对象,那么之后的 request 阶段中间件会被跳过,但这实际指的是中间件里的那几种方法,对于本方法,还是要调用的。这就意味着,process_respnse() 的处理过程不应依赖于 process_request() 的结果,因为他们是可能被跳过的,但本方法不会。

处理 StreamingHttpResponse

更新于 django 1.5

response 也可以是一个 StreamingHttpResponse。

不像 HttpResponse,StreamingHttpResponse 并没有 content 属性。因此,中间件不可以再默认 response 对象总是有 content 属性。如果他们要处理 content,那么应当提前检查:


   
if response.streaming: response.streaming_content = wrap_streaming_content(response.streaming_content) else : response.content = alter_content(response.content)

注意:streaming_content 应当总是被认为太大而不能保存在内存里。对其的处理应当通过生成器来实现:


   
def wrap_streaming_content(content) for chunk in content: yield alter_content(chunk)

 

process_exception(request,exception)

当 view 抛出异常时,本方法就会被调用。本方法应当返回 None 或一个 HttpResponse 对象,如果返回 response,那么此方法所在中间件外层的 response 阶段中间件将继续被调用;如果返回 None,则由默认异常处理机制来接手。

这个钩子可以用来发送错误通知,写入日志文件,甚至恢复错误。

 

__init__()

一般中间件并不需要初始化数据,如果确实需要,则可以定义在此方法内。不过需要注意:

  • django 初始化中间件时并不会传入多余的参数,所以本方法只接受一个 self
  • 不像 process_* 这些方法会对每一个 request 调用,本方法只会在服务器第一次响应时进行

因此,本方法更多是作为一种自检机制在使用。因为中间件框架提供了一种运行时停用某个中间件的方法,就是引发一个 django.core.exceptions.MiddlewareNotUsed 异常。那么 __init__() 方法就可以利用这一点在服务开始时进行自检。

转载于:https://my.oschina.net/lionets/blog/220130

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值