Django 詳解 中間件Middleware
Django中間件
還是涉及到django的請求生命周期。middle ware 請求穿過中間件到達url,再經過中間件返回給用戶。
簡單實例
django項目根目錄新建一個Middle文件夾,再新建一個test.py文件
在test文件中寫入;其中的類必須繼承 from django.utils.deprecation import MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): def process_request(self, request):print(‘m1‘) def process_response(self, request, response): print(‘m1_r‘) return response class M2(MiddlewareMixin): def process_request(self, request): print(‘m2‘) def process_response(self, request, response): print(‘m2_r‘) return response classM3(MiddlewareMixin): def process_request(self, request): print(‘m3‘) def process_response(self, request, response): print(‘m3_r‘) return response
將你的測試中間件加入Django的中間件配置中,settings文件
隨便建一組對應路由。
在index函數裏面寫上
def index(request): print(‘到達‘) return HttpResponse(‘ok‘)
查看結果:
此時如果給某個中間件的process_request返回一個HttpResponse:
#!/user/bin/env python # -*-coding: utf-8-*- from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse class M1(MiddlewareMixin): def process_request(self, request): print(‘m1‘) def process_response(self, request, response): print(‘m1_r‘) return response class M2(MiddlewareMixin): def process_request(self, request): print(‘m2‘) return HttpResponse(‘中斷‘) # 這裏返回 def process_response(self, request, response): print(‘m2_r‘) return response class M3(MiddlewareMixin): def process_request(self, request): print(‘m3‘) def process_response(self, request, response): print(‘m3_r‘) return response
查看下結果
可能你好像懂了,但是並沒有,真正的中間件過程其實還有一個process_view.
View Code自定制中間件的另一種方式
下面是最新的django2.1文檔內的自定制中間件的另一種寫法。
一個中間件工廠是可以被調用的,它接收一個可調用的get_response方法並返回一個中間件。中間件也是可調用的,它接收請求並返回響應,就像一個view視圖
def simple_middleware(get_response): # 一次性配置和初始化 def middleware(request): # 在每個請求之前被執行的代碼 #這個視圖(和後面的中間件)被調用 response = get_response(request) # 在每個請求或者響應之後代碼被執行 # the view is called. return response return middleware
或者他也可以被重寫成一個實例可以被調用的類,像這個:
class SimpleMiddleware: def __init__(self, get_response): self.get_response = get_response # 一次性配置和初始化 def __call__(self, request): # 在每一次請求之前代碼被執行 # 視圖或者接下來的中間件被調用 response = self.get_response(request) # 在每個請求或者響應之後代碼將會被執行 # the view is called. return response
可調用的get_response是由django提供的,可以是真實的視圖函數或者也可以是鏈上的下一個中間件。當前的中間件不需要具體精確地知道或者關心它是什麽,只是它代表接下來執行(到來的)是什麽。
上面是一個小小的簡化,可調用的get_response如果在中間件的最後一位,將不會是一個真實的視圖函數,更可能是處理的一個外部包裝方法,它關註於應用視圖中間件,調用視圖和合適的URL參數,並且使用template和exception中間件.
中間件可以生存在你的Python路徑的任何地方。
__init__(get_response)
中間件工廠必須接收一個get_response參數,你也可以為中間件初始化一些全局的狀態。記住下面的這幾點
1、django只能使用get_response參數來初始化你的中間件,所以你不能定義__init__()來需要其他的參數
2、跟__call__()方法每次請求被調用不同,__init__()方法只會被調用一次,當web服務啟動的時候
例如
class LoginMiddleware: def __init__(self, get_response): self.get_response = get_response @method_decorator(adminlogin) def __call__(self, request): if request.method == "PUT": request.data = dict(urllib.parse.parse_qsl(request.body.decode())) request.data.update(request.GET.dict()) elif request.method == "POST": request.data = request.POST.copy().dict() response = self.get_response(request) return response
詳情請查閱django(version2.1)文檔:https://docs.djangoproject.com/en/2.1/topics/http/middleware/
Django 詳解 中間件Middleware