django中間件,在http請求 到達視圖函數之前 和視圖函數return之後,django會根據自己的規則在合适的時機執行中間件中相應的方法。
看圖了解中間件
django中間件的執行順序如上圖示
無論是在請求到達view視圖之前還是在response傳回給使用者之前,我們都可以進行攔截到,然後做自己的處理然後在給view處理,或者傳回給使用者。
這裡介紹django中間件可以定義的五種方法:
1.process_request(self,request) 2.process_view(self, request, callback, callback_args, callback_kwargs) 3.process_template_response(self,request,response) 4.process_exception(self, request, exception) 5.process_response(self, request, response)
1.process_request(self,request)方法
這個方法是執行在request請求到達view視圖之前,它可以攔截下來,将使用者的headers、body、meta已經使用者要請求的路由等等後可以攔截到,然後處理自己需要的邏輯。
應用:
1、可以在這裡列印日志,将使用者請求的路由、攜帶的headers、傳來的body、GET參數等全部列印到日志裡面
2、可以在這裡判斷使用者是否有權限進入這個路由,沒有權限就可以将使用者跳轉到其他路由。
def process_request(self,request):
print('===============================================')
print('攔截請求的位址:',request.path)
request_dic = json.loads(request.body, encoding='utf-8')
print(request_dic)
2.process_view(self, request, callback, callback_args, callback_kwargs)
(1)執行完所有中間件的request方法‘
(2)url比對成功
(3)拿到 視圖函數的名稱、參數,(注意不執行) 再執行process_view()方法
(4)最後去執行視圖函數
這個方法發生在已經走過路由,即将到達vie視圖函數。
可以拿到view視圖函數,這裡的用法筆者目前也沒有用到,後續用到再次追加。
3.process_template_response(self,request,response)
這個方法,隻有在視圖函數的傳回對象中有render方法才會執行!
并把對象的render方法的傳回值傳回給使用者(注意不傳回視圖函數的return的結果了,而是傳回視圖函數 return值(對象)的render方法)
同樣,這裡的用法筆者目前也沒有用到,後續用到再次追加。
4.process_exception(self, request, exception)
這個方法在view視圖裡面出現未知的錯誤時會執行,
應用:
在view視圖函數出現未知的錯誤時,将使用者重定向到其他頁面,防止使用者界面出現錯誤導緻的使用者體驗下降。
def process_exception(self,request,exception):
print('發生錯誤的請求位址',request.path,exception.__str__)
return render(request,'Home.html')
5.process_response(self, request, response)
這個方法,執行在response傳回給使用者之前,開發者可以在這裡将需要修改的response内容修改後,再次傳回給使用者。
應用:
例如筆者遇到需要處理使用者的翻譯問題,那麼不可能在每個view視圖函數裡面再意義一一翻譯,這樣肯定是不可取的。那麼就可以在這裡response到達使用者之前,判斷語言環境之後将翻譯處理好,然後傳回給使用者。
def process_response(self,request,response):
if request.META.get('HTTP_LANGUAGE') == 'en':
translation_file_path = os.path.dirname(os.path.abspath(__file__)) + '/translation_file.txt'
with open(translation_file_path,'r') as f:
trans_list = f.read().split('\n')
dic = json.loads(response.content, encoding='utf-8')
for item in trans_list:
if dic['message'] in item:
item_tran_list = item.split(';')
dic['message'] = item_tran_list[]
f.close()
response.content = json.dumps(dic)
return response
最後放上筆者圖檔中使用到的中間件整體代碼
from django.http import HttpResponse
import json,os
# 繼承自一個檔案
from django.shortcuts import render
from django.utils.deprecation import MiddlewareMixin
# 注意寫完之後要在setings裡面進行注冊 在MIDDLEARE裡面注冊使用
class myMiddle(MiddlewareMixin):
def process_request(self,request):
print('===========================================')
print('攔截請求的位址:',request.path)
request_dic = json.loads(request.body, encoding='utf-8')
print(request_dic)
def process_exception(self,request,exception):
print('發生錯誤的請求位址',request.path,exception.__str__)
return render(request,'Home.html')
def process_response(self,request,response):
response_dic = json.loads(response.content,encoding='utf-8')
print(response_dic)
return response