day68 Django--中介軟體
一,中介軟體介紹
1.什麼是中介軟體?
中介軟體是一個用來處理Django的請求和響應的框架級別的鉤子(函式)。它是一個輕量、低級別的外掛系統,用於在全域性範圍內改變Django的輸入和輸出。每個中介軟體元件都負責做一些特定的功能。
但是由於其影響的時全域性,所以需要謹慎使用,使用不當會影響效能。
中介軟體事幫助我們在檢視函式執行之前和執行之後都可以做一些額外的操作,它本質上就是一個自定義類,類中定義了幾個方法,Django框架會在請求的特定時間去執行這些方法。
2.Django專案中的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.MD1', #自定義中介軟體MD1
'middlewares.MD2', #自定義中介軟體MD2
]
MIDDLEWARE配置項是一個列表,列表中是一個個字串,這些字串其實是一個個類,也就是一個個中介軟體。
二,Django中自定義中介軟體
1.五個方法(執行的時間點、執行的順序、引數、返回值)
1.process_request
有一個引數,就是request,這個request和檢視函式中的request是一樣的。
process_request(self,request) ***** 0.執行的時間點 收到請求的時候,執行檢視函式之前執行的 1.執行順序: 1.按照中介軟體的註冊順序執行 2.引數 當前請求物件 3.返回值 1.返回None繼續執行後續的 2.返回響應物件,直接返回響應,不繼續執行後續的是檢視函式
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1裡面的 process_request") class MD2(MiddlewareMixin): def process_request(self, request): print("MD2裡面的 process_request") pass
2.process_response
response是檢視函式返回的HttpResponse物件。該方法的返回值也必須是HttpResponse物件
process_response(self,request,response) ***** 0.執行的時間點: 返回響應之後 1.執行順序 按照中介軟體的註冊倒序執行 2.引數 1.request:當前的請求物件 2.response:傳遞過來的響應物件 3.返回值 1.必須返回一個響應物件
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1裡面的 process_request") def process_response(self, request, response): print("MD1裡面的 process_response") return response class MD2(MiddlewareMixin): def process_request(self, request): print("MD2裡面的 process_request") pass def process_response(self, request, response): print("MD2裡面的 process_response") return response
3.process_view
該方法有四個引數:
view_func是Django即將使用的檢視函式(它是實際的函式物件,而不是函式的名稱作為字串)
view_args是將傳遞給檢視的位置引數的列表
view_kwargs是將傳遞給檢視的關鍵字引數的字典。view_args和view_kwargs都不包含第一個檢視引數(request)
如果它返回一個HttpResponse物件,Django不會呼叫適當的檢視函式。它將執行中介軟體的process_response方法並將應用到該HttpResponse並返回結果。
process_view(self,request,view_func,view_args,view_kwargs) 0.執行的時間點: process_request之後,檢視函式之前執行 1.執行順序: 按照註冊的順序執行 2.引數 1.request:請求物件 2.view_func:將要執行的檢視函式物件 3.view_args/view_kwargs:將要執行的函式的引數 3.返回值 1.None:繼續往後執行 2.響應物件:直接返回了,不會執行後續的檢視函式
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1裡面的 process_request") def process_response(self, request, response): print("MD1裡面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 中的process_view") print(view_func, view_func.__name__) class MD2(MiddlewareMixin): def process_request(self, request): print("MD2裡面的 process_request") pass def process_response(self, request, response): print("MD2裡面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 中的process_view") print(view_func, view_func.__name__)
4.process_exception
exception引數是檢視函式異常產生的Exception物件。這個方法只有在檢視函式中出現異常了才執行,它返回的值可以是一個None也可以是一個HttpResponse物件。如果是HttpResponse物件,Django將呼叫模板和中介軟體中的process_response方法,並返回給瀏覽器,否則將預設處理異常。如果返回一個None,則交給下一個中介軟體的process_exception方法來處理異常。它的執行順序也是按照中介軟體註冊順序的倒序執行。
process_exception(self,request,exception) 0.執行的時間點 當檢視函式中丟擲異常的時候才會執行這個方法 1.執行順序: 註冊的倒序 2.引數: 1.request:請求物件 2.exception:檢視函式丟擲的異常 3.返回值: 1.None:繼續執行後續 2.響應物件:直接返回
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1裡面的 process_request") def process_response(self, request, response): print("MD1裡面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 中的process_exception")
return HttpResponse(str(exception)) class MD2(MiddlewareMixin): def process_request(self, request): print("MD2裡面的 process_request") pass def process_response(self, request, response): print("MD2裡面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 中的process_exception")
想辦法,在檢視函式中丟擲一個異常:
def index(request): print("app01 中的 index檢視") raise ValueError("呵呵") return HttpResponse("O98K")
5.process_template_response
它其中一個的引數,response是TemplateResponse物件(有檢視函式或者中介軟體產生)。
它是在檢視函式執行完成後立即執行,但是它有一個前提條件,那就是檢視函式返回的物件有一個render()方法
process_template_response(self,request,response) 0.執行的時間點 當檢視函式中返回帶render方法的響應物件,這個方法才會執行 1.執行順序: 註冊的倒序 2.引數 1.request:請求物件 2.response:響應物件 3.返回值 1.必須返回響應物件
class MD1(MiddlewareMixin): def process_request(self, request): print("MD1裡面的 process_request") def process_response(self, request, response): print("MD1裡面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 中的process_exception") return HttpResponse(str(exception)) def process_template_response(self, request, response): print("MD1 中的process_template_response") return response class MD2(MiddlewareMixin): def process_request(self, request): print("MD2裡面的 process_request") pass def process_response(self, request, response): print("MD2裡面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 中的process_exception") def process_template_response(self, request, response): print("MD2 中的process_template_response") return response
views.py中:
def index(request): print("app01 中的 index檢視") def render(): print("in index/render") return HttpResponse("O98K") rep = HttpResponse("OK") rep.render = render return rep
三,Django請求流程