[Django] 소스 해석django 시작 및 접근 프로세스 (2)

Django 부팅 프로세스 (2)
지난 편에서는 시작 파라미터가'django'에 전달되었다고 말했습니다.core.management.commands.runserver.Command.handle'을 처리하고 다음은 원본 코드를 계속 해석합니다.
django.core.management.commands.runserver.Command.handle
    def handle(self, *args, **options):
    	#  DEBUG  ,   settings   ALLOWED_HOSTS
        if not settings.DEBUG and not settings.ALLOWED_HOSTS:
            raise CommandError('You must set settings.ALLOWED_HOSTS if DEBUG is False.')
		#   socket    ipv6
        self.use_ipv6 = options['use_ipv6']
        if self.use_ipv6 and not socket.has_ipv6:
            raise CommandError('Your Python does not support IPv6.')
        self._raw_ipv6 = False
        #       ip:port,     ip port,  ip      
        if not options['addrport']:
            self.addr = ''
            self.port = self.default_port
        else:
       		#     
            m = re.match(naiveip_re, options['addrport'])
            if m is None:
                raise CommandError('"%s" is not a valid port number '
                                   'or address:port pair.' % options['addrport'])
			#         IP                                           
            self.addr, _ipv4, _ipv6, _fqdn, self.port = m.groups()
            #          
            if not self.port.isdigit():
                raise CommandError("%r is not a valid port number." % self.port)
            # ip     
            if self.addr:
                if _ipv6:
                    self.addr = self.addr[1:-1]
                    self.use_ipv6 = True
                    self._raw_ipv6 = True
                elif self.use_ipv6 and not _fqdn:
                    raise CommandError('"%s" is not a valid IPv6 address.' % self.addr)
        # ip       
        if not self.addr:
            self.addr = self.default_addr_ipv6 if self.use_ipv6 else self.default_addr
            self._raw_ipv6 = self.use_ipv6
        #           ,      
        #        run  
        self.run(**options)

매개 변수가 검사에 들어간 후'django.'에 건네주었습니다.core.management.commands.runserver.Command.run'계속 처리.
django.core.management.commands.runserver.Command.run
    def run(self, **options):
        """Run the server, using the autoreloader if needed."""
        #           
        use_reloader = options['use_reloader']
		#       ,     inner_run  
        if use_reloader:
            autoreload.run_with_reloader(self.inner_run, **options)
        else:
        	#     
            self.inner_run(None, **options)

'django'호출core.management.commands.runserver.Command.inner_run'서비스를 시작합니다.
django.core.management.commands.runserver.Command.inner_run
    def inner_run(self, *args, **options):
    	...
        #       
        self.check(display_num_errors=True)
        #          
        self.check_migrations()
		...
		#   ‘django.contrib.staticfiles.management.commands.runserver.get_handler’  ;
		#       ‘django.core.management.commands.runserver.Command.get_handler’  ;
		# ‘get_handler’    ‘django.core.servers.basehttp.get_internal_wsgi_application’  ;
		# ‘get_internal_wsgi_application’   settings      'WSGI_APPLICATION';
		#          ‘django.core.wsgi.get_wsgi_application’;
		# ‘get_wsgi_application’   django         ,   setting  ,  app        ;
		#     'django.core.handlers.wsgi.WSGIHandler'     ,     handler  ;
		#            ,  DEBUG           ‘--insecure’,     StaticFilesHandler handler    ;
        handler = self.get_handler(*args, **options)
        #   ‘django.core.servers.basehttp.run’  , WSGIServer    
        run(self.addr, int(self.port), handler, ipv6=self.use_ipv6, threading=threading, server_cls=self.server_cls)
        ...

시스템 검사, 데이터베이스 이전 검사를 통해 WSGIHandler 실례 대상을 획득한 후'django.core.servers.basehttp.run'은(는) WSGIServer 서비스를 시작합니다.
django.core.handlers.wsgi.WSGIHandler
class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        #      load_middleware     
        #      convert_exception_to_response    self._get_response    handler,
        #  settings.MIDDLEWARE      , handler                 ,
        #             convert_exception_to_response       handler,
        #       handler                       ,
        #         python     ,           。
        #           self.get_response=self._get_response       mw_instance,
        #  mw_instance  ‘process_view’    ‘settings.MIDDLEWARE’        self._view_middleware
        #  mw_instance ‘process_template_response’    ‘settings.MIDDLEWARE’        self._template_response_middleware
        #  mw_instance ‘process_exception’    ‘settings.MIDDLEWARE’        self._exception_middleware
        #           process_request->process_view->  response render    process_template_response->         process_exception->process_response
        # convert_exception_to_response(mw_instance)     ,   self._middleware_chain
        # convert_exception_to_response        ,               
        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 = 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'):
            response = environ['wsgi.file_wrapper'](response.file_to_stream)
        return response

WSGIHandler는 인스턴스화 과정에서 중간부품을 로드했습니다.
django.core.servers.basehttp.run
def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=WSGIServer):
	#       
    server_address = (addr, port)
    #      ,      --nothreading       
    if threading:
    	#  socketserver.ThreadingMixIn WSGIServer     
    	# httpd_cls = class WSGIServer(socketserver.ThreadingMixIn,WSGIServer):...
        httpd_cls = type('WSGIServer', (socketserver.ThreadingMixIn, server_cls), {
     })
    else:
        httpd_cls = server_cls
    httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
    if threading:
        # ThreadingMixIn.daemon_threads indicates how threads will behave on an
        # abrupt shutdown; like quitting the server by the user or restarting
        # by the auto-reloader. True means the server will not wait for thread
        # termination before it quits. This will make auto-reloader faster
        # and will prevent the need to kill the server manually if a thread
        # isn't terminating correctly.
        httpd.daemon_threads = True
    # WSGIHandler
    httpd.set_app(wsgi_handler)
    #    socketserver.TCPServer.serve_forever()    server_address
    #           WSGIHandler __call__(),  request response
    httpd.serve_forever()

run 방법은 TCPServer 서비스를 시작합니다. 이 서비스는 감청 내용을 WSGI RequestHandler에 맡기고self를 처리합니다.응용 프로그램은 이전에 가져온 WSGIHandler 인스턴스로 설정됩니다.여기까지django 시작 과정의 원본 코드 해석을 기본적으로 완성했고 그 중에서 중간부품의 불러오는 과정을 이해했다. 다음 편에서는django의 요청 과정을 계속 소개할 것이다.

좋은 웹페이지 즐겨찾기