Django框架详细介绍---中间件(认证)
一、緒論
在cookie和session的應(yīng)用中,通過在視圖函數(shù)內(nèi)添加裝飾器判斷用戶是否登錄,把沒有登錄的用戶請求跳轉(zhuǎn)到登錄頁面,通過給幾個特定視圖函數(shù)加裝飾器實現(xiàn)了這個需求。但是以后添加的視圖函數(shù)可能也需要加上裝飾器,這樣是不是稍微有點繁瑣
在此,通過中間件可通過簡單適宜的方式實現(xiàn)認證等操作
二、中間件
1.什么是中間件
中間件是一個用來處理Django的請求和響應(yīng)的框架級別的鉤子,是一個輕量、低級別的插件系統(tǒng),用于在全局范圍內(nèi)改變Django的輸入和輸出。每個中間件組件都負責(zé)做一些特定的功能。
但是由于其影響的是全局,所以需要謹(jǐn)慎使用,使用不當(dāng)會影響性能
簡單的說,中間件是幫助我們在視圖函數(shù)執(zhí)行之前和執(zhí)行之后都可以做一些額外的操作,它本質(zhì)上就是一個自定義類,在類中定義方法,Django框架會在請求的特定的時間去執(zhí)行相應(yīng)的方法
Django本身在setting.py中自定義了一些中間件,MIDDLEWARE配置項是一個列表,列表中存放字符串,這些字符串其實就是類,也就是中間件:
MIDDLEWARE = [
# 安全相關(guān)
'django.middleware.security.SecurityMiddleware',
# session相關(guān),Django每次接收到request請求的時候會
# 給request添加session方法,所以在視圖內(nèi)可通過原點的方式調(diào)用session
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# csrf 校驗
'django.middleware.csrf.CsrfViewMiddleware',
# 認證相關(guān)
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
2.自定義中間件
process_request(self,request) process_view(self, request, view_func, view_args, view_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response)
可自定義以上五種中間件,通常使用的也就process_request和process_response,這些方法的返回值可以是一個None或一個HttpResponse對象,如果是None,則繼續(xù)按照django定義的規(guī)則向后繼續(xù)執(zhí)行,如果是HttpResponse對象,則直接將該對象返回給用戶
附:Django處理請求、響應(yīng)的過程
示例:
class Exemple(MiddlewareMixin):
def process_request(self, request):
print("Exemple中process_request方法")
def process_view(self, request, view_func, view_args, view_kwargs):
print("Exemple中process_view方法")
print(view_func.__name__)
# return HttpResponse("Excemple中的process_view方法")
# def process_response(self, request, response):
# print("Exemple中的process_response方法")
# return response
1)prosess_request
process_request有一個參數(shù),就是request,這個request和視圖函數(shù)中的request是一樣的,返回值可以是None也可以是HttpResponse對象
返回值是None的話,按正常流程繼續(xù)走,交給下一個中間件處理,如果是HttpResponse對象,Django將不執(zhí)行視圖函數(shù),而將相應(yīng)對象返回給瀏覽器
多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執(zhí)行的,也就是說第一個中間件的process_request方法首先執(zhí)行,而它的process_response方法最后執(zhí)行,最后一個中間件的process_request方法最后一個執(zhí)行,它的process_response方法是最先執(zhí)行
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect, render
class Login(MiddlewareMixin):
def process_request(self, request):
print("Login中process_request方法")
class Exemple(MiddlewareMixin):
def process_request(self, request):
print("Exemple中process_request方法")
在settings.py的MIDDLEWARE配置項中注冊自定義中間件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 注冊自定義中間件
'middlewares.login_middlewares.Login',
'middlewares.login_middlewares.Exemple',
]
2)process_response
有兩個參數(shù),一個是request,一個是response,request就是上述例子中一樣的對象,response是視圖函數(shù)返回的HttpResponse對象,該方法的返回值也必須是HttpResponse對象
多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執(zhí)行的,也就是說第一個中間件的process_request方法首先執(zhí)行,而它的process_response方法最后執(zhí)行,最后一個中間件的process_request方法最后一個執(zhí)行,它的process_response方法是最先執(zhí)行
3)process_view
process_view(self, request, view_func, view_args, view_kwargs)該方法有四個參數(shù)
request HttpRequest對象 view_func Django即將使用的視圖函數(shù)(它是實際的函數(shù)對象,而不是函數(shù)的名稱作為字符串) view_args 將傳遞給視圖的位置參數(shù)的列表 view_kwargs 將傳遞給視圖的關(guān)鍵字參數(shù)的字典。 view_args和view_kwargs都不包含第一個視圖參數(shù)(request)
Django會在調(diào)用視圖函數(shù)之前調(diào)用process_view方法,它應(yīng)該返回None或一個HttpResponse對象:
如果返回None,Django將繼續(xù)處理這個請求,執(zhí)行任何其他中間件的process_view方法,然后在執(zhí)行相應(yīng)的視圖
如果它返回一個HttpResponse對象,Django不會調(diào)用適當(dāng)?shù)囊晥D函數(shù),它將執(zhí)行中間件的process_response方法并將應(yīng)用到該HttpResponse并返回結(jié)果
process_view方法是在process_request之后,視圖函數(shù)之前執(zhí)行的,執(zhí)行順序按照MIDDLEWARE中的注冊順序從前到后順序執(zhí)行的
4)process_exception
process_exception(self, request, exception)該方法有兩個參數(shù)
request HttpRequest對象 exception 視圖函數(shù)異常產(chǎn)生的Exception對象
只有在視圖函數(shù)中出現(xiàn)異常了才執(zhí)行,它返回的值可以是一個None也可以是一個HttpResponse對象:
如果是HttpResponse對象,Django將調(diào)用模板和中間件中的process_response方法,并返回給瀏覽器,否則將默認處理異常
如果返回一個None,則交給下一個中間件的process_exception方法來處理異常。它的執(zhí)行順序也是按照中間件注冊順序的倒序執(zhí)行
5)process_template_response
process_template_response(self, request, response)該方法有兩個參數(shù)
request HttpRequest對象 exception TemplateResponse對象,由視圖函數(shù)或者中間件產(chǎn)生
視圖函數(shù)執(zhí)行完成后立即執(zhí)行,但是它有一個前提條件,那就是視圖函數(shù)返回的對象有一個render()方法,順序是倒序(或者表明該對象是一個TemplateResponse對象或等價方法)
3.中間件的執(zhí)行過程
請求到達中間件之后,先按照正序執(zhí)行每個注冊中間件的process_reques方法,process_request方法返回的值是None,就依次執(zhí)行,如果返回的值是HttpResponse對象,不再執(zhí)行后面的process_request方法,而是執(zhí)行當(dāng)前對應(yīng)中間件的process_response方法,將HttpResponse對象返回給瀏覽器
舉例說明:如果MIDDLEWARE中注冊了6個中間件,執(zhí)行過程中,第3個中間件返回了一個HttpResponse對象,那么后面的第4、5、6的中間件的process_request和process_response方法都不執(zhí)行,倒序執(zhí)行第3-第1之間的中間件的process_response方法
process_request方法都執(zhí)行完后,匹配路由,找到要執(zhí)行的視圖函數(shù),先不執(zhí)行視圖函數(shù),先執(zhí)行中間件中的process_view方法,process_view方法返回None,繼續(xù)按順序執(zhí)行,所有process_view方法執(zhí)行完后執(zhí)行視圖函數(shù),加入中間件3的process_view方法返回了HttpResponse對象,則4,5,6的process_view以及視圖函數(shù)都不執(zhí)行,直接從最后一個中間件,也就是中間件6的process_response方法開始倒序執(zhí)行
process_template_response和process_exception兩個方法的觸發(fā)是有條件的,執(zhí)行順序也是倒序
示例:Django中基于中間件的認證登錄
1)Django目錄下創(chuàng)建存放自定義中間件的包,創(chuàng)建中間件的py文件
注意:自定義的中間件必須繼承MiddlewareMixin
中間件登錄認證時需要依靠session,所以數(shù)據(jù)庫中需要創(chuàng)建好django_session表
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
class Login(MiddlewareMixin):
def process_request(self, request):
url = request.path_info
if not request.path_info.startswith("/login/"):
login_flag = request.session.get("login")
if not login_flag:
rep = redirect("/login/?next={}".format(url))
return rep
2)在setting.py中注冊中間件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 注冊自定義的中間件
'middlewares.login_middlewares.Login',
]
總結(jié):
# 每個中間件都有五種可重寫的方法
process_request(self,request)
1.在urls.py之前執(zhí)行
2.按照列表中的注冊順序執(zhí)行
3.返回值:返回None不做任何處理繼續(xù)后面的
返回響應(yīng)對象,直接跳出,后面的中間件、urls.py都不再執(zhí)行
process_view(self, request, view_func, view_args, view_kwargs)
1.在urls.py之后以及views.py之前執(zhí)行
2.按照列表中的注冊順序執(zhí)行
3.返回值:返回None放行
返回響應(yīng)對象,就直接跳出,倒序依次執(zhí)行所有中間件的process_response方法
process_response(self, request, response)
1.在views.py之后執(zhí)行
2.按照列表中的注冊倒序執(zhí)行
3.返回值:必須有返回值,返回的是相應(yīng)對象
process_template_response(self,request,response)
process_exception(self, request, exception)
總結(jié)
以上是生活随笔為你收集整理的Django框架详细介绍---中间件(认证)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绝区零鲨鱼妹艾莲乔配队推荐攻略
- 下一篇: 挣钱的游戏软件哪个最靠谱(传奇打金一天二