什么是中间件
在有些场合,需要对Django处理的每个 request 都执行某段代码。这类代码可能是在 view 处理之前修改传入的 request,或者记录日志信息以便于调试,等等。这类功能可以用 Django 的中间件框架来实现,该框架由切入到 Django 的 request/response 处理过程中的钩子集合组成。 这个轻量级低层次的 plug-in 系统,能用于全面的修改 Django 的输入和输出。
安装中间件
要启用一个中间件,只需将其添加到配置模块的 MIDDLEWARE_CLASSES 元组中。 在 MIDDLEWARE_CLASSES
中,中间件组件用字符串表示: 指向中间件类名的完整Python路径。 例如,下面是 django-admin.py startproject 创建的缺省 MIDDLEWARE_CLASSES :
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
Django项目的安装并不强制要求任何中间件,如果你愿意, MIDDLEWARE_CLASSES 可以为空。
这里中间件出现的顺序非常重要。 在 request 和 view 的处理阶段,Django 按照 MIDDLEWARE_CLASSES 中出现的顺序来应用中间件,而在 response 和异常处理阶段,Django 则按逆序来调用它们。 也就是说,Django 将 MIDDLEWARE_CLASSES 视为 view 函数外层的顺序包装子: 在 request 阶段按顺序从上到下穿过,而在 response 则反过来。
中间件方法
init
__init__(self)
在中间件类中, init() 方法用于执行系统范围的设置。出于性能的考虑,每个已启用的中间件在每个服务器进程中只初始化 一 次。 也就是说 init() 仅在服务进程启动的时候调用,而在针对单个 request 处理时并不执行。
对一个 middleware 而言,定义 init() 方法的通常原因是检查自身的必要性。 如果 init() 抛出异常 django.core.exceptions.MiddlewareNotUsed ,则 Django 将从 middleware 栈中移出该 middleware。可以用这个机制来检查 middleware 依赖的软件是否存在、服务是否运行于调试模式、以及任何其它环境因素。
在中间件中定义 init() 方法时,除了标准的 self 参数之外,不应定义任何其它参数。
process_request
process_request(self, request)
process_request() 应当返回 None 或 HttpResponse 对象.
- 如果返回 None , Django将继续处理这个request,执行后续的中间件,然后调用相应的view.
- 如果返回 HttpResponse 对象, Django 将不再执行 任何 其它的中间件(而无视其种类)以及相应的view。 Django将立即返回该 HttpResponse .
process_view
process_view(self, request, view, args, kwargs)
这个方法的调用时机在 Django 执行完 request 预处理函数并确定待执行的 view 之后,但在 view 函数实际执行之前。
process_response
process_response(self, request, response)
这个方法的调用时机在 Django 执行 view 函数并生成 response 之后。这个方法的参数相当直观: request 是 request 对象,而 response 则是从 view 中返回的 response 对象。
不同可能返回 None 的request和view预处理函数, process_response() 必须 返回 HttpResponse 对象.这个response对象可以是传入函数的那一个原始对象(通常已被修改),也可以是全新生成的。
process_exception
process_exception(self, request, exception)
这个方法只有在 request 处理过程中出了问题并且 view 函数抛出了一个未捕获的异常时才会被调用。这个钩子可以用来发送错误通知,将现场相关信息输出到日志文件, 或者甚至尝试从错误中自动恢复。
这个函数的参数除了一贯的 request 对象之外,还包括 view 函数抛出的实际的异常对象 exception 。
process_exception() 应当返回 None 或 HttpResponse 对象.
- 如果返回 None , Django将用框架内置的异常处理机制继续处理相应request。
- 如果返回 HttpResponse 对象, Django 将使用该response对象,而短路框架内置的异常处理机制。