1. 瀏覽器解析輸入的url
2. 尋找url對應的ip位址
3. 透過ip位址存取我們的伺服器
a . 請求進入wsgi伺服器(我在這裡省略了可能存在的代理伺服器,例如nginx)
b. wsgi伺服器將請求包裝後,傳遞給django應用
c. django應用根據請求路徑找到對應的處理函數進行處理
d. 處理完成後,django應用程式將回應傳回給wsgi伺服器
e. wsgi伺服器將django套用傳回的回應包裝後,回傳回應
4. 伺服器回傳回應內容,瀏覽器渲染輸出
wsgi服務透過wsgi協定和django應用程式進行通信,wsgi服務是server端,django應用是application,server端透過django提供的application_callable函數去呼叫djano應用,application_callable函數處理完成後,將回應傳回給server
django的application_callable函式在django.core.handlers.wsgi.py檔案中,server服務端處理每個請求時會呼叫WSGIHandler這個類別
#wsgi.py文件 class WSGIHandler(base.BaseHandler): request_class = WSGIRequest def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) 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 = list(response.items()) for c in response.cookies.values(): response_headers.append(('Set-Cookie', c.output(header=''))) 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類別在初始化時,先載入中間件,將要請求的函數_get_response用中間件封裝起來(中間件相當於裝飾器),執行的時候,中間件就會執行
# wsgi.py文件
# wsgi.py文件 def load_middleware(self): ... self._view_middleware = [] self._template_response_middleware = [] self._exception_middleware = [] handler = convert_exception_to_response(self._get_response) for middleware_path in reversed(settings.MIDDLEWARE): middleware = import_string(middleware_path) try: mw_instance = middleware(handler) except MiddlewareNotUsed as exc: ... handler = convert_exception_to_response(mw_instance) self._middleware_chain = handler
接下來,就是請求調用WSGIHandler
1. 實例化一個request_class
2. 透過get_response取得請求,get_response最終會呼叫被中間件封裝後的函式_get_response
def _get_response(self, request): 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 ... 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) ... return response
_get_response函數中,首先會根據url找到要呼叫的視圖函數 resolver_match = resolver.resolve(request.path_info),然後呼叫視圖函數 response = wrapped_callback(request, *callback_args, **callback_kwargs)kwargs)
回傳response(在_get_response裡面也是會呼叫一些的中間件的)至此再將response回傳給server,整個請求流程完畢四、總結django對於一個請求,主要過程就是尋找請求對應的視圖函數,呼叫被中間件封裝後的視圖函數,回傳回應。【推薦課程:Django影片教學
】###以上是django源碼分析之請求流程的詳細內容。更多資訊請關注PHP中文網其他相關文章!