首頁  >  文章  >  後端開發  >  django源碼分析之請求流程

django源碼分析之請求流程

little bottle
little bottle轉載
2019-04-08 17:48:182064瀏覽

Django 專案是一個Python定制框架,它源自於一個線上新聞 Web 站點,於 2005 年以開源的形式被釋放出來。本文將對django的請求流程進行原始碼分析。

一、從瀏覽器發出一個請求,到回傳回應內容,這個過程是怎麼樣的?

1. 瀏覽器解析輸入的url

2. 尋找url對應的ip位址

3. 透過ip位址存取我們的伺服器

  a .  請求進入wsgi伺服器(我在這裡省略了可能存在的代理伺服器,例如nginx)

  b.  wsgi伺服器將請求包裝後,傳遞給django應用

  c.  django應用根據請求路徑找到對應的處理函數進行處理

  d.  處理完成後,django應用程式將回應傳回給wsgi伺服器

  e. wsgi伺服器將django套用傳回的回應包裝後,回傳回應

4. 伺服器回傳回應內容,瀏覽器渲染輸出

二、django應用程式的處理入口

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

三、django處理請求流程

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中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除