为什么中间件 mixin 在 django.utils.deprecation.py 中声明
Why middleware mixin declared in django.utils.deprecation.py
在路径 django.utils.deprecation.py
中,我们有一些 class 关于方法的弃用警告。
在该文件中我们有一个名为 MiddlewareMixin
的 class。这个 class 用于编写中间件 classes。虽然与弃用无关,但为什么这个 class 写在这个路径中?
简而言之:它是一个将弃用中间件变成新中间件的工具,尽管它有一些限制。
Django 的中间件 "style" 已经改变。这个 MiddlewareMixin
在大多数情况下可以 "convert" 一个老式的中间件 class 到一个新式的中间件 decorator,正如 [=28] 中所写=]:
class django.utils.deprecation.MiddlewareMixin
(...)
In most cases, inheriting from this mixin will be sufficient to make an old-style middleware compatible with the new system with sufficient backwards-compatibility. The new short-circuiting semantics will be harmless or even beneficial to the existing middleware. In a few cases, a middleware class may need some changes to adjust to the new semantics.
在"old days"(在django-1.10之前),中间件是这样写的:
class SomeMiddleware:
def process_request(self, request):
# ...
pass
def process_response(self, request, response):
# ...
return response
但是如今,中间件更多地被视为 "underlying middleware" 周围的某种 "decorator",最终是视图。如 documentation on the new middleware 中指定:
A middleware can be written as a function that looks like this:
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
通过引入一个新的"style",你可以看到旧的中间件本身就是"deprecated",这当然很遗憾,因为现在编写的所有中间件都将失效。
然而 MiddlewareMixin
能够在现代中间件中转换这样的 old 中间件,它通过覆盖 __call__
函数来实现,因此调用process_request
和 process_response
之间,就像我们在 source code [GitHub]:
中看到的
class MiddlewareMixin:
def __init__(self, get_response=None):
self.get_response = get_response
super().__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
response = response or self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
因此,我们在这里通过覆盖 __call__
函数使对象 可调用 ,从而模仿新样式中 def middleware(request)
的工作方式。然而,如果在旧的中间件中, __call__
也被覆盖,那么这当然会导致一些问题。此外,旧式中间件有一些功能,如 process_view
、process_exception
和 process_template_response
,此处不再使用。但我觉得这些都不是很 "popular" 反正。
在路径 django.utils.deprecation.py
中,我们有一些 class 关于方法的弃用警告。
在该文件中我们有一个名为 MiddlewareMixin
的 class。这个 class 用于编写中间件 classes。虽然与弃用无关,但为什么这个 class 写在这个路径中?
简而言之:它是一个将弃用中间件变成新中间件的工具,尽管它有一些限制。
Django 的中间件 "style" 已经改变。这个 MiddlewareMixin
在大多数情况下可以 "convert" 一个老式的中间件 class 到一个新式的中间件 decorator,正如 [=28] 中所写=]:
class django.utils.deprecation.MiddlewareMixin
(...)
In most cases, inheriting from this mixin will be sufficient to make an old-style middleware compatible with the new system with sufficient backwards-compatibility. The new short-circuiting semantics will be harmless or even beneficial to the existing middleware. In a few cases, a middleware class may need some changes to adjust to the new semantics.
在"old days"(在django-1.10之前),中间件是这样写的:
class SomeMiddleware:
def process_request(self, request):
# ...
pass
def process_response(self, request, response):
# ...
return response
但是如今,中间件更多地被视为 "underlying middleware" 周围的某种 "decorator",最终是视图。如 documentation on the new middleware 中指定:
A middleware can be written as a function that looks like this: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
通过引入一个新的"style",你可以看到旧的中间件本身就是"deprecated",这当然很遗憾,因为现在编写的所有中间件都将失效。
然而 MiddlewareMixin
能够在现代中间件中转换这样的 old 中间件,它通过覆盖 __call__
函数来实现,因此调用process_request
和 process_response
之间,就像我们在 source code [GitHub]:
class MiddlewareMixin: def __init__(self, get_response=None): self.get_response = get_response super().__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) response = response or self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response
因此,我们在这里通过覆盖 __call__
函数使对象 可调用 ,从而模仿新样式中 def middleware(request)
的工作方式。然而,如果在旧的中间件中, __call__
也被覆盖,那么这当然会导致一些问题。此外,旧式中间件有一些功能,如 process_view
、process_exception
和 process_template_response
,此处不再使用。但我觉得这些都不是很 "popular" 反正。