亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

從請求到響應過程中django都做了哪些處理

發布時間:2020-09-19 15:30:37 來源:腳本之家 閱讀:188 作者:創宇前端 欄目:開發技術

前言

最近面試的時候,被面試官問道一個問題,就是 request.user 里面的 user 是怎樣得到的,這個問題當時沒有回答上來,可以說是非常的尷尬,所以趕快查了一些資料,看了一些源碼,特地來總結一下這個問題。

要想回答為什么可以直接通過 request.user 得到請求的用戶,應該先來看看請求被處理以及如何返回響應的流程。今天先總結一下 django 從請求到響應都進行了哪些過程。

WSGI

當客戶端發送一次請求后,最先處理請求的實際上是 web 服務器就是我們經常說的 nginx、Apache 這類的 web 服務器,而 WSGI 的作用就是把 web 服務器和 web 框架 (Django) 連接起來。WSGI 被分為了兩個部分:服務端和應用端。為了處理一個 WSGI 的響應,服務端執行應用程序并向應用端提供一個回調函數,應用端處理請求并使用提供的回調將響應返回給服務端。

本質上來講,我覺得 WSGI 就是 web 服務器和 django 應用之間的一個聯系人。

數據流

當用戶向你的應用發送一個請求的時候,一個 WSGI handler 將會被初始化,它會完成以下工作:

  1. 導入 settings.py 和 django 的異常類
  2. 使用 load_middleware 方法加載 settings.py 中 MIDDLEWARE_CLASSES 或者 MIDDLEWARES 元組中所用的 middleware classes.
  3. 創建四個列表 (_request_middleware,_view_middleware, _response_middleware, _exception_middleware),里面分別包含處理 request,view,response 和 exception 的方法。
  4. WSGI Handler 將實例化一個 django.http.HTTPRequest 對象的子類,django.core.handlers.wsgi.WSGIRequest.
  5. 循環遍歷處理 request 的方法 (_request_middleware 列表),并按照順序調用他們
  6. 解析請求的 url
  7. 循環遍歷每個處理 view 的方法 (_view_middleware 列表)
  8. 如果找的到的話,就調用視圖函數
  9. 處理任何異常的方法 (_exception_middleware 列表)
  10. 循環遍歷每個處理響應的方法 (_response_middleware 列表),(從內向外,與請求中間件的順序相反)
  11. 最后得到一個響應,并調用 web server 提供的回調函數

中間件

中間件被用在了 django 的許多關鍵功能中:例如,使用 CSRF 中間鍵來防止跨站請求偽造攻擊。它們也被用來處理會話數據,身份認證和授權同樣是由中間件來完成的。我們也可以自己編寫中間件來調整或者(短路)通過應用程序的數據流。

django 的中間件至少含有以下四個方法中的一個:process_request, process_response, process_view, process_exception。這些方法會被 WSGI handler 收集并按照順序調用。

process_request

我們可以先來看看 django.contrib.auth.middleware.AuthenticationMiddleware:

def get_user(request):
 if not hasattr(request, '_cached_user'):
  request._cached_user = auth.get_user(request)
 return request._cached_user

class AuthenticationMiddleware(MiddlewareMixin):
 def process_request(self, request):
  assert hasattr(request, 'session'), (
    "The Django authentication middleware requires session middleware "
    "to be installed. Edit your MIDDLEWARE%s setting to insert "
    "'django.contrib.sessions.middleware.SessionMiddleware' before "
    "'django.contrib.auth.middleware.AuthenticationMiddleware'."
  ) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
  request.user = SimpleLazyObject(lambda: get_user(request))

這里我們可以發現 request.user 這個屬性是在 AuthenticationMiddleware 中產生的。這個我們稍后再說。

這里我們可以發現,這個中間件只有 process_request,說明它只在 request 這一步處理流入和流出 django 應用的數據流。這個中間件會首先驗證會話中間件是否被使用,然后通過調用 get_user 函數來設置用戶。當 WSGI 處理程序迭代

process_request 方法列表的時候,它將會構建這個最終會被傳遞給視圖函數的請求對象,并能夠使你引用 request.user。一些中間件沒有 process_request 方法,在這個階段,會被跳過。

process_request 應該返回 None 或者 HTTPResponse 對象。當返回 None 時,WSGI handler 會繼續加載 process_request 里面的方法,但是后一種情況會短路處理過程并進入 process_response 循環。

解析 url

當所有的 process_request 被調用完之后,我們就會得到一個將被傳遞給視圖函數的 request 對象。當這個事件發生之前,django 必須解析 url 并決定調用哪一個視圖函數。這個過程非常簡單,只需要使用正則匹配即可。settings.py 中有一個 ROOT_URLCONF 鍵來指定根 url.py,在這里會包含你所有 app 的 urls.py 文件。如果沒有匹配成功,將會拋出一個異常 django.core.urlresolvers.Resolver404, 這是 django.http.HTTP404 的子類。

process_view

到這一步之后 WSGI handler 知道了調用哪一個視圖函數,以及傳遞哪些參數。它會再一次調用中間件列表里面的方法,這次是_view_middleware 列表。所有 Django 中間件的 process_view 方法將會被這樣聲明:

process_view(request, view_function, view_args, view_kwargs)

和 process_request 一樣,process_view 函數必須返回 None 或者 HTTPResponse 對象,使得 WSGI handler 繼續處理視圖或者'短路'處理流程并返回一個響應。在 CSRF middleware 中存在一個 process_view 的方法。作用是當 CSRF cookies 出現時,process_view 方法將會返回 None, 視圖函數將會繼續的執行。如果不是這樣,請求將會被拒絕,處理流程將會被'短路',會生成一個錯誤的信息。

進入視圖函數

一個視圖函數需要滿足三個條件:

  • 必須是可以調用的。這可以是基于函數的視圖或者是 class-based 的視圖(繼承自 View 并且使用 as_view() 方法來使它成為可調用的。這些方法的調用依賴 HTTP verb(GET, POST, etc))
  • 必須接受一個 HTTPRequest 對象作為第一個位置參數。這個 HTTPRequest 對象是被所有 process_request 和 process_view 中間件方法處理的結果。
  • 必須返回一個 HTTPResponse 對象,或者拋出一個異常。就是用這個 response 對象來開啟 WSGI handler 的 process_view 循環。

process_exception

如果視圖函數拋出一個異常,Handler 將會循環遍歷_exception_middleware 列表,這些方法按照相反的順序執行,從 settings.py 里面列出來的最后一個中間件到第一個。如果一個異常被拋出,處理過程將會被短路,其他的 process_exception 將不會被執行。通常我們依賴 Djnago's BaseHandler 提供的異常處理程序,但是我們也可以使用自定義的異常處理中間件。

process_response

在這個階段,我們得到了一個 HTTPResponse 對象,這個對象可能是 process_view 返回的,也可能是視圖函數返回的。現在我們將循環訪問響應中間件。這是中間件調整數據的最后的機會。執行的順序是從內向外執行。

以 cache middleware 的 process_response 為例:它依賴于你的 app 里面的不同的狀態(緩存是否打開或者關閉,是否在處理一個數據流),來決定是否緩存你的響應。

注意

django 1.10 和之前版本的區別:

在舊版本的 MIDDLEWARE_CLASSES 中,就算一個中間件”短路”了執行過程,所有的中間件都會調用它們的 process_response 方法。而在新的 MIDDLEWARES 版本中,只有這個中間件和在它之前執行的中間件才會調用 process_response 方法。

總結

以上就是 django 在處理一個請求的基本的過程,最后 django 的 WSGI Handler 會創建一個來自 HTTPResponse 的返回值,而且會調用回調函數把數據傳遞給 web server, 最后返回給用戶。

以下是兩個關鍵點:

我們現在知道了視圖函數是如何和 url 解析器匹配以及什么在調用它 (WSGI Handler)

有四個關鍵的地方可以讓你掛鉤到請求 / 響應周期:process_request, process_response, process_view, process_exception。請求中間件是從外部向內執行,最后抵達到視圖函數,然后通過響應中間件從內向外返回。

參考資料

  • Django Middlewares and the Request/Response Cycle
  • How Django processes a request

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

会理县| 莱芜市| 庆阳市| 金平| 防城港市| 遂溪县| 承德县| 那曲县| 青神县| 亳州市| 定日县| 汨罗市| 陇西县| 额济纳旗| 江永县| 苗栗市| 正蓝旗| 鄱阳县| 南充市| 新龙县| 鹤庆县| 红河县| 榆林市| 镇雄县| 昭通市| 罗田县| 明溪县| 农安县| 合作市| 高要市| 通榆县| 盐城市| 金昌市| 长宁县| 江阴市| 山阳县| 惠安县| 大姚县| 永吉县| 禹州市| 大方县|