zoukankan      html  css  js  c++  java
  • Django之request进入中间件《一》

    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进行合法检验; process_response对核心函数self._get_response执行后返回的response进行验证"""
    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()

  • 相关阅读:
    UIPath RPA 自动化脚本 机器人从入门到精通
    [转]面向物联网的21个开源软件项目
    数字化转型
    区块链项目大全-项目源码链接收藏
    SAP HANA学习资料大全 Simple Finane + Simple Logisitic [非常完善的学习资料汇总]
    今日头条技术架构分析
    巴菲特价值投资的六项法则
    文档大师 2016 :在电脑和头脑中快速找到文档的文件管理软件
    文档大师 在Win10 IE11下,文档集画面无法正常显示Word等Office文档的解决方法
    人脑+电脑:通过文档管理让个人能力大大拓展
  • 原文地址:https://www.cnblogs.com/zengmu/p/12932459.html
Copyright © 2011-2022 走看看