1. 瀏覽器解析輸入的url
2. 查找url對(duì)應(yīng)的ip地址
3. 通過(guò)ip地址訪問(wèn)我們的服務(wù)器
a. 請(qǐng)求進(jìn)入wsgi服務(wù)器(我在這里省略了可能存在的代理服務(wù)器,比如nginx)
b. wsgi服務(wù)器將請(qǐng)求包裝后,傳遞給django應(yīng)用
c. django應(yīng)用根據(jù)請(qǐng)求路徑找到相應(yīng)的處理函數(shù)進(jìn)行處理
d. 處理完成后,django應(yīng)用將響應(yīng)返回給wsgi服務(wù)器
e. wsgi服務(wù)器將django應(yīng)用返回的響應(yīng)包裝后,返回響應(yīng)
4. 服務(wù)器返回響應(yīng)內(nèi)容,瀏覽器渲染輸出
wsgi服務(wù)通過(guò)wsgi協(xié)議和django應(yīng)用進(jìn)行通信,wsgi服務(wù)是server端,django應(yīng)用是application,server端通過(guò)django提供的application_callable函數(shù)去調(diào)用djano應(yīng)用,application_callable函數(shù)處理完成后,將響應(yīng)返回給server
django的application_callable函數(shù)在django.core.handlers.wsgi.py文件中,server服務(wù)端處理每個(gè)請(qǐng)求時(shí)會(huì)調(diào)用WSGIHandler這個(gè)類
#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類在初始化時(shí),首先加載中間件,將要請(qǐng)求的函數(shù) _get_response用中間件封裝起來(lái)(中間件相當(dāng)于裝飾器),執(zhí)行的時(shí)候,中間件就會(huì)執(zhí)行
# 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
接下來(lái),就是請(qǐng)求調(diào)用WSGIHandler
1. 實(shí)例化一個(gè)request_class
2. 通過(guò)get_response獲取請(qǐng)求,get_response最終會(huì)調(diào)用被中間件封裝后的函數(shù) _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函數(shù)中,首先會(huì)根據(jù)url找到要調(diào)用的視圖函數(shù) resolver_match = resolver.resolve(request.path_info),然后調(diào)用視圖函數(shù) response = wrapped_callback(request, *callback_args, **callback_kwargs)返回response(在_get_response里面也是會(huì)調(diào)用一些的中間件的)
至此再將response返回給server,整個(gè)請(qǐng)求流程完畢
django對(duì)于一個(gè)請(qǐng)求,主要過(guò)程就是尋找請(qǐng)求對(duì)應(yīng)的視圖函數(shù),調(diào)用被中間件封裝后的視圖函數(shù),返回響應(yīng)。
【推薦課程:Django視頻教程】
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com