中间件¶
中间件是Django请求/响应处理的钩子框架。它是一个轻巧的低级“插件”系统,用于全局改变Django的输入或输出。
每个中间件组件负责执行某些特定功能。例如,Django包含一个中间件组件 AuthenticationMiddleware
,它将用户与使用会话的请求相关联。
本文档介绍了中间件的工作原理,如何激活中间件以及如何编写自己的中间件。Django附带了一些你可以直接使用的内置中间件。它们记录在内置的中间件参考中。
编写自己的中间件¶
中间件工厂是一个可调用的,它可以get_response
调用并返回一个中间件。中间件是一个可调用的,它接收请求并返回响应,就像视图一样。
中间件可以编写为如下所示的函数:
def simple_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
或者它可以写成一个实例可调用的类,如下所示:
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
get_response
是Django提供的可调用可能是实际视图(如果这是最后列出的中间件),或者它可能是链中的下一个中间件。当前的中间件不需要知道或关心它到底是什么,只是它表示接下来要发生的事情。
以上是一个简单的简化 - get_response
链中最后一个中间件的可调用性不是实际视图,而是处理程序的包装器方法,它负责应用视图中间件,使用适当的URL参数调用视图,并应用模板- 响应和 异常中间件。
中间件可以存在于Python路径的任何位置。
__init__(get_response)
¶
中间件工厂必须接受get_response
争论。您还可以初始化中间件的某些全局状态。请记住以下几点:
- Django仅使用
get_response
参数初始化您的中间件,因此您无法定义__init__()
为需要任何其他参数。 - 与
__call__()
每个请求调用一次的方法不同,当Web服务器启动时,__init__()
只调用一次。
将中间件标记为未使用¶
在启动时确定是否应该使用一块中间件有时很有用。在这些情况下,您的中间件的__init__()
方法可能会提高MiddlewareNotUsed
。然后Django会删除从中间件进程中间件和日志调试消息给django.request当记录器DEBUG
是True
。
激活中间件¶
要激活中间件组件,请将其添加到MIDDLEWARE
Django设置中的列表中。
在MIDDLEWARE
,每个中间件组件由一个字符串表示:中间件工厂的类或函数名称的完整Python路径。例如,这是由以下创建的默认值:django-admin startproject
Django安装不需要任何中间件 - MIDDLEWARE
如果您愿意,可以是空的 - 但强烈建议您至少使用CommonMiddleware
。
重要的顺序是MIDDLEWARE
因为中间件可以依赖于其他中间件。例如, AuthenticationMiddleware
将经过身份验证的用户存储在会话中; 因此,必须追求它 SessionMiddleware
。有关Django中间件类的排序的一些常见提示,请参阅 中间件排序。
中间件订单和分层¶
在请求阶段,在调用视图之前,Django按其定义的顺序MIDDLEWARE
(自上而下)应用中间件。
你可以把它想象成一个洋葱:每个中间件类都是一个包裹视图的“层”,它位于洋葱的核心。如果请求通过洋葱的所有层(每个层调用get_response
将请求传递到下一层),一直到核心的视图,响应将通过每个层(以相反的顺序)回来的路。
如果其中一个层决定短路并返回响应而没有调用它get_response
,那么该层内的洋葱层(包括视图)都不会看到请求或响应。响应将仅通过请求传入的相同层返回。
其他中间件钩子¶
除了前面描述的基本请求/响应中间件模式之外,您还可以向基于类的中间件添加其他三种特殊方法:
process_view()
¶
process_view
(request,view_func,view_args,view_kwargs)¶
request
是一个HttpRequest
对象。view_func
是Django即将使用的Python函数。(它是实际的函数对象,而不是作为字符串的函数的名称。)view_args
是将传递给视图的位置参数列表,并且view_kwargs
是将传递给视图的关键字参数的字典。既不 view_args
也不view_kwargs
包括第一视图参数(request
)。
process_view()
在Django调用视图之前调用。
它应该返回一个None
或一个HttpResponse
对象。如果它返回None
,Django将继续处理此请求,执行任何其他process_view()
中间件,然后是相应的视图。如果它返回一个HttpResponse
对象,Django将不会打扰调用适当的视图; 它将响应中间件应用于该 HttpResponse
并返回结果。