Django中间件初始化过程(草稿)

def load_middleware(self):
"""
Populate middleware lists from settings.MIDDLEWARE.

Must be called after the environment is fixed (see __call__ in subclasses).
"""
self._view_middleware = []
self._template_response_middleware = []
self._exception_middleware = []

handler = convert_exception_to_response(self._get_response) #为返回视图的函数,包一层出错函数处理异常。如果出错,返回出错的response,如果没出错,返回_get_response返回的东西
for middleware_path in reversed(settings.MIDDLEWARE):
middleware = import_string(middleware_path)
try:
mw_instance = middleware(handler)
except MiddlewareNotUsed as exc:
if settings.DEBUG:
if str(exc):
logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc)
else:
logger.debug('MiddlewareNotUsed: %r', middleware_path)
continue

if mw_instance is None:
raise ImproperlyConfigured(
'Middleware factory %s returned None.' % middleware_path
)

if hasattr(mw_instance, 'process_view'):
self._view_middleware.insert(0, mw_instance.process_view)
if hasattr(mw_instance, 'process_template_response'):
self._template_response_middleware.append(mw_instance.process_template_response)
if hasattr(mw_instance, 'process_exception'):
self._exception_middleware.append(mw_instance.process_exception)

handler = convert_exception_to_response(mw_instance)

# We only assign to this when initialization is complete as it is used
# as a flag for initialization being complete.
self._middleware_chain = handler


def _get_response(self, request):
"""
Resolve and call the view, then apply view, exception, and
template_response middleware. This method is everything that happens
inside the request/response middleware.
"""
response = None

if hasattr(request, 'urlconf'):
urlconf = request.urlconf
set_urlconf(urlconf)
resolver = get_resolver(urlconf)
else:
resolver = get_resolver()

resolver_match = resolver.resolve(request.path_info) #从请求url获取视图
callback, callback_args, callback_kwargs = resolver_match #获取视图函数,以及传参
request.resolver_match = resolver_match

# Apply view middleware
for middleware_method in self._view_middleware:
response = middleware_method(request, callback, callback_args, callback_kwargs) #在调用视图前调用view中间件,注意,如果有返回response,将不调用视图函数
if response:
break

if response is None:
wrapped_callback = self.make_view_atomic(callback) #为每个视图封装一个事务
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs) #调用视图函数
except Exception as e:
response = self.process_exception_by_middleware(e, request)

# Complain if the view returned None (a common error). #调用视图之后返回response为空的异常处理
if response is None:
if isinstance(callback, types.FunctionType): # FBV
view_name = callback.__name__
else: # CBV
view_name = callback.__class__.__name__ + '.__call__'

raise ValueError(
"The view %s.%s didn't return an HttpResponse object. It "
"returned None instead." % (callback.__module__, view_name)
)

# If the response supports deferred rendering, apply template
# response middleware and then render the response
elif hasattr(response, 'render') and callable(response.render):
for middleware_method in self._template_response_middleware:
response = middleware_method(request, response)
# Complain if the template response middleware returned None (a common error).
if response is None:
raise ValueError(
"%s.process_template_response didn't return an "
"HttpResponse object. It returned None instead."
% (middleware_method.__self__.__class__.__name__)
)

try:
response = response.render()
except Exception as e:
response = self.process_exception_by_middleware(e, request)

return response




猜你喜欢

转载自www.cnblogs.com/EmptyRabbit/p/11390299.html