[Django] 원본 해석 Django 시작 및 접근 프로세스 (4)

Django 액세스 프로세스(둘)
Django 방문 과정 (1) 에서 우리는 요청 내용이 django에 들어갔다는 것을 알게 되었다.core.handlers.wsgi.WSGIHandler.__call__처리를 진행하고, 다음은 우리가 이어서 원본 코드를 계속 해석할 것이다.
django.core.handlers.wsgi.WSGIHandler.call
class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # django                          。
        self.load_middleware()

    def __call__(self, environ, start_response):
    	#       
        set_script_prefix(get_script_name(environ))
        #     requet    
        #       runserver    ,     ‘django.core.management.base.BaseCommand’ ,
        #  BaseCommand    'from django.db import DEFAULT_DB_ALIAS, connections'      ,
        #  db.__init__.py    request_started    。
        '''
        #       ,  reset_queries         
        signals.request_started.connect(reset_queries)
        #       ,  close_old_connections         
        signals.request_started.connect(close_old_connections)
        #       ,  close_old_connections         
		signals.request_finished.connect(close_old_connections)
        '''
        signals.request_started.send(sender=self.__class__, environ=environ)
        #  WSGIRequest  request,            request   。
        request = self.request_class(environ)
        #     
        #  request       
       	#                  response 
        response = self.get_response(request)
        # 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)
	        #                 __call__  
	        #                     
	        response = self._middleware_chain(request)
	        response._closable_objects.append(request)
	        if response.status_code >= 400:
	            log_response(
	                '%s: %s', response.reason_phrase, request.path,
	                response=response,
	                request=request,
	            )
	        return response
		'''
      	#          :
       	'''
		class MiddlewareMixin:
		    def __init__(self, get_response=None):
		    	#     load_middleware()         ,
		    	#    django.core.handlers.base.BaseHandler._get_response
		        self.get_response = get_response
		        super().__init__()
		
		    def __call__(self, request):
		        response = None
		        if hasattr(self, 'process_request'):
		        	#       process_request    ,            
		        	#  request       
		        	#                    response
		            response = self.process_request(request)
		        #    requets  django.core.handlers.base.BaseHandler._get_response  
		        #             ,
		        #                     ,       
		        #    requset、                  process_view  ,            
		        #            response render  ,
		        #    response      process_template_response    ,            ;
		        #       response  ,        process_exception        ,            。
		        response = response or self.get_response(request)
		        if hasattr(self, 'process_response'):
		        	#     request response      process_response    ,            
		            response = self.process_response(request, response)
		        #       response
		        return response
       	'''
       	# django.core.handlers.base.BaseHandler._get_respons
       	'''
   	    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)
	        callback, callback_args, callback_kwargs = resolver_match
	        request.resolver_match = resolver_match
	
	        # Apply view middleware
	        #       process_viewf  
	        for middleware_method in self._view_middleware:
	            response = middleware_method(request, callback, callback_args, callback_kwargs)
	            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).
	        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
	        #       process_template_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
       	'''
       	
        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()),
        ]
        #        TCPServer WSGIRequestHandler         ,
        #                      ServerHandler,
        #   ServerHandler run      socket   wsgiref.handlers.BaseHandler.start_response   WSGIHandler __call__,
        #      header  ,status     
        start_response(status, response_headers)
        # wsgiref.handlers.BaseHandler.start_response
        '''
        def start_response(self, status, headers,exc_info=None):
        	"""'start_response()' callable as specified by PEP 3333"""

	        if exc_info:
	            try:
	                if self.headers_sent:
	                    # Re-raise original exception if headers sent
	                    raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
	            finally:
	                exc_info = None        # avoid dangling circular ref
	        elif self.headers is not None:
	            raise AssertionError("Headers already set!")
	
	        self.status = status
	        self.headers = self.headers_class(headers)
	        status = self._convert_string_type(status, "Status")
	        assert len(status)>=4,"Status must be at least 4 characters"
	        assert status[:3].isdigit(), "Status message must begin w/3-digit code"
	        assert status[3]==" ", "Status message must have a space after code"
	
	        if __debug__:
	            for name, val in headers:
	                name = self._convert_string_type(name, "Header name")
	                val = self._convert_string_type(val, "Header value")
	                assert not is_hop_by_hop(name),\
	                       f"Hop-by-hop header, '{name}: {val}', not allowed"
	
	        return self.write
        '''
        if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'):
            response = environ['wsgi.file_wrapper'](response.file_to_stream)
        #       response   django.core.servers.basehttp.ServerHandler.run self.result,
        #     self.finish_response()       self.wfile           。
        return response

이를 통해 알 수 있듯이django의 방문 과정은 다음과 같다.
Created with Rapha l 2.2.0 클라이언트 (브라우저) 가 TCP 요청을 시작하여 TCPServer가 WSGIRequestHandler를 감청하도록 요청합니다.handle ServerHandler.run WSGIHandler.__call__ WSGIRequest 봉인 Request가 중간부품에 전달되는processrequest에서response를 가져오시겠습니까?중간부품에 Request와response를 건네주는 프로세스response response 처리 후 self.wfile는 클라이언트에게 루트가 일치하는 보기 함수에 따라 중간부품에 전달하는processview가 구체적인 보기 함수에 전달됩니까?응답 내용에 템플릿을 렌더링해야 합니까?중간부품에 넘기는 프로세스template_response를 구체적인render 방법에 맡기면 렌더링이 제대로 실행됩니까?리퀘스트와response를 중간부품에 넘기는process 로 되돌아오기response response 처리 후 self.wfile은 클라이언트에게 중간부품에 건네주는processexception 중간부품에 맡긴 프로세스exception yes no yes no yes no yes no

좋은 웹페이지 즐겨찾기