前言
最近面試的時候,被面試官問道一個問題,就是 request.user 里面的 user 是怎樣得到的,這個問題當時沒有回答上來,可以說是非常的尷尬,所以趕快查了一些資料,看了一些源碼,特地來總結一下這個問題。
要想回答為什么可以直接通過 request.user 得到請求的用戶,應該先來看看請求被處理以及如何返回響應的流程。今天先總結一下 django 從請求到響應都進行了哪些過程。
WSGI
當客戶端發送一次請求后,最先處理請求的實際上是 web 服務器就是我們經常說的 nginx、Apache 這類的 web 服務器,而 WSGI 的作用就是把 web 服務器和 web 框架 (Django) 連接起來。WSGI 被分為了兩個部分:服務端和應用端。為了處理一個 WSGI 的響應,服務端執行應用程序并向應用端提供一個回調函數,應用端處理請求并使用提供的回調將響應返回給服務端。
本質上來講,我覺得 WSGI 就是 web 服務器和 django 應用之間的一個聯系人。
數據流
當用戶向你的應用發送一個請求的時候,一個 WSGI handler 將會被初始化,它會完成以下工作:
中間件
中間件被用在了 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_userclass 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))
新聞熱點
疑難解答