Django之resquest进入中间件《一》

时间:2020-05-21
本文章向大家介绍Django之resquest进入中间件《一》,主要包括Django之resquest进入中间件《一》使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
     #在wsgihandler生成实例时,在__init__魔方方法里面就进行了加载中间件 self.load_middleware()
def __call__(self, environ, start_response): set_script_prefix(get_script_name(environ)) signals.request_started.send(sender=self.__class__, environ=environ)
     #封装成request对象 request
= self.request_class(environ) response = self.get_response(request) response._handler_class = self.__class__ status = '%d %s' % (response.status_code, response.reason_phrase) response_headers = [ *response.items(), *(('Set-Cookie', c.output(header='')) for c in response.cookies.values()), ] start_response(status, response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): # If `wsgi.file_wrapper` is used the WSGI server does not call # .close on the response, but on the file wrapper. Patch it to use # response.close instead which takes care of closing all files. response.file_to_stream.close = response.close response = environ['wsgi.file_wrapper'](response.file_to_stream, response.block_size) return response

load_middleware函数:

    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 = []
# 封装 这个时候就已经把slef._get_response函数绑定到了装饰器的inner函数上面
        handler = convert_exception_to_response(self._get_response)

        for middleware_path in reversed(settings.MIDDLEWARE):

            middleware = import_string(middleware_path)
            try:
"""遍历中间件,通过下面的黄色标记并在中间件类上层层包裹上一级中间件,通过类的__call__魔方方法达到动态添加装饰器的效果,
每个中间件中的process_request方法对进来的request进行合法检验"""
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 )
#在加载中间件时,将核心对view,response进行检验的钩子函数添加到列表中,为下一步检验做准备
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

进入get_response()函数

    def get_response(self, request):
        """Return an HttpResponse object for the given HttpRequest."""
        # Setup default url resolver for this thread
        set_urlconf(settings.ROOT_URLCONF)
#根据程序上下文 找到 slef._middleware_chain = handler= convert_exception_to_response(middlerinstance)
而且这个handler 是一个装饰器
response
= self._middleware_chain(request) response._resource_closers.append(request.close) if response.status_code >= 400: log_response( '%s: %s', response.reason_phrase, request.path, response=response, request=request, ) return response

当运行self._middleware_chain(request),会先进行上述我们添加的中间件类中的process_request方法对request中的首部关键字进行合法性检验,然后调用核心函数self._get_response():

      

   ps:这与我们在setting中定义的middleware是一致顺序,因为在加载的时候用的reverse函数,和多层装饰器执行顺序一样,是一个后进先出的栈的效果:

      

总结就是:serverhandler实例化时,就会加载中间件,将核心函数self._get_response()AOP修饰各种中间件函数保存到列表里面为下一步认证做准备,然后通过中间件类的回调方法实现动态添加各种中间件类的process_request方法装饰核心函数-------成为一个多层装饰器。

所以当调用get_response时,会先进行一些列的process_request认证,然后才开始执行核心函数self._get_response()

原文地址:https://www.cnblogs.com/zengmu/p/12932459.html