中间件方法
现在,我们已经知道什么是中间件和怎么安装它,下面将介绍中间件类中可以定义的所有方法。
Initializer: __init__(self)「初始化]
在中间件类中, __init__()
方法用于执行系统范围的设置。
出于性能的考虑,每个已启用的中间件在每个服务器进程中只初始化 一 次。也就是说 __init__()
仅在服务进程启动的时候调用,而在针对单个request处理时并不执行。
对一个middleware而言,定义 __init__()
方法的通常原因是检查自身的必要性。 如果 __init__()
抛出异常 django.core.exceptions.MiddlewareNotUsed
,则Django将从middleware栈中移出该middleware。 可以用这个机制来检查middleware依赖的软件是否存在、服务是否运行于调试模式、以及任何其它环境因素。
在中间件中定义 __init__()
方法时,除了标准的 self
参数之外,不应定义任何其它参数。
Request预处理函数: process_request(self, request)
这个方法的调用时机在Django接收到request之后,但仍未解析URL以确定应当运行的view之前。 Django向它传入相应的 HttpRequest
对象,以便在方法中修改。
process_request()
应当返回 None
或 HttpResponse
对象:
- 如果返回 None,Django将继续处理这个request,执行后续的中间件,然后调用相应的view。
- 如果返回
HttpResponse
对象, Django 将不再执行任何其它的中间件(而无视其种类)以及相应的view。 Django将立即返回该HttpResponse
。
View预处理函数: process_view(self, request, view, args, kwargs)
这个方法的调用时机在Django执行完request预处理函数并确定待执行的view之后,但在view函数实际执行之前。
表15-1列出了传入到这个View预处理函数的参数。
表 15-1. 传入process_view()
的参数
参数 | 说明 |
---|---|
request | HttpRequest 对象。 |
view | Django处理HttpRequest对象将调用的函数.这里是实际的函数对象,而不是函数名字符串。 |
args | 将传入view的位置参数列表,但不包括request 参数(它通常是传 入view的第一个参数) |
kwargs | 将传入view的关键字参数字典。 |
就像process_request()
一样,process_view()
会返回None
或者一个HttpResponse
对象
- 如果返回None,Django会继续处理这个
request
,执行其他middleware调用适当的view. - 如果返回的是
HttpResponse
对象,Django不会再处理其他middleware
而是直接返回该HttpResponse
对象。
Response后处理函数: process_response(self, request, response)
这个方法的调用时机在Django执行view函数并生成response之后。这个处理可以改变response的内容。比较常见的用法是内容压缩,比如gzip。
这个方法的参数相当直观: request
是request对象,而 response
则是从view中返回的response
对象。
不同可能返回 None
的request和view预处理函数, process_response()
必须 返回 HttpResponse
对象。这个response对象可以是传入函数的那一个原始对象(通常已被修改),也可以是全新生成的。
Exception后处理函数: process_exception(self, request, exception)
这个方法只有在request处理过程中出了问题并且view函数抛出了一个未捕获的异常时才会被调用。 这个钩子可以用来发送错误通知,将现场相关信息输出到日志文件,或者甚至尝试从错误中自动恢复。
这个函数的参数除了一贯的 request
对象之外,还包括view函数抛出的实际的异常对象 exception
。
process_exception()
应当返回 None
或 HttpResponse
对象。
- 如果返回
None
, Django将用框架内置的异常处理机制继续处理相应request
。 - 如果返回
HttpResponse
对象, Django 将使用该response
对象,而短路框架内置的异常处理机制。
备注
Django自带了相当数量的中间件类(将在随后章节介绍),它们都是相当好的范例。阅读这些代码将使你对中间件的强大有一个很好的认识。
在Djangos wiki上也可以找到大量的社区贡献的中间件范例: http://code.djangoproject.com/wiki/ContributedMiddleware
{$ activeFileHint $}