日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

day62 中间件

發布時間:2025/3/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 day62 中间件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.中間件的介紹 

  中間件顧名思義,是介于request與response處理之間的一道處理過程,相對比較輕量級,

并且在全局上改變django的輸入與輸出。因為改變的是全局,所以需要謹慎實用,

用不好會影響到性能

?

  1.?Django 的請求生命周期

?

  2.Django默認自帶的一些中間件

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', ]

?  3.執行中間件的過程

?

?二. 自定義中間件

  1.在項目中創建一個包

  在項目中創建一個包,隨便起名字,一般都放在一個叫做utils的包里面,

表示一個公用的組件,創建一個py文件,隨便起名字,

例如叫做:middlewares.py,內容如下

?

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):#自定義中間件,不是必須要有下面這兩個方法,有request方法說明請求來了要處理,
有response方法說明響應出去時需要處理,不是非要寫這兩個方法,如果你沒寫process_response方法,
那么會一層一層的往上找,哪個中間件有process_response方法就將返回對象給哪個中間件def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return response

?

  2.在 settings.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','utils.middlewares.MD1', # 自定義中間件MD1,這個寫的是你項目路徑下的一個路徑,
                例如,如果你放在項目下,文件夾名成為utils,
                那么這里應該寫utils.middlewares.MD1'utils.middlewares.MD2' # 自定義中間件MD2 ]

?

三.常用方法

  1. process_request?

process_request有一個參數,就是request,這個request和

    視圖函數中的request是一樣的。它的返回值可以是None也可以是HttpResponse對象。返回值是None的話,

    按正常流程繼續走,交給下一個中間件處理,如果是HttpResponse對象,

    Django將不執行視圖函數,而將相應對象返回給瀏覽器。

?

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")pass

  ①在注冊時 先注冊 MD1 再注冊 MD2,打印結果為:

MD1里面的 process_request MD2里面的 process_request app01 中的 index視圖

  ②在注冊時 先注冊MD2 再注冊 MD1,打印結果為:

MD2里面的 process_request MD1里面的 process_request app01 中的 index視圖 注:
  多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執行的,

也就是說第一個中間件的process_request方法首先執行,而它的process_response

方法最后執行,最后一個中間件的process_request方法最后一個執行,

它的process_response方法是最先執行。

?

  2. process_response

  它有兩個參數,一個是request,一個是response,request就是上述例子中一樣的對象,

response是視圖函數返回的HttpResponse對象。該方法的返回值也必須是HttpResponse對象。

  ①示例1:

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")#不必須寫return值def process_response(self, request, response):#request和response兩個參數必須有,名字隨便取print("MD1里面的 process_response")#print(response.__dict__['_container'][0].decode('utf-8')) #查看響應體里面的內容的方法return response #必須有返回值,寫return response ,這個response就像一個接力棒一樣#return HttpResponse('瞎搞') ,如果你寫了這個,那么你視圖返回過來的內容就被它給替代了class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")passdef process_response(self, request, response): #request和response兩個參數必須要有,名字隨便取print("MD2里面的 process_response") return response #必須返回response,不然你上層的中間件就沒有拿到httpresponse對象,就會報錯

  結果:

MD2里面的 process_request MD1里面的 process_request app01 中的 index視圖 MD1里面的 process_response MD2里面的 process_response 看結果可知:process_response方法是在視圖函數之后執行的,并且順序是MD1比MD2先執行。

(此時settings.py中 MD2比MD1先注冊)多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執行的,

也就是說第一個中間件的process_request方法首先執行,而它的process_response方法最后執行,

最后一個中間件的process_request方法最后一個執行,它的process_response方法是最先執行。

  ②示例2:

from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponseclass Md1(MiddlewareMixin):def process_request(self,request):print("Md1請求")
     return HttpResponse("Md2中斷")      #process_request方法里面不寫返回值,默認也是返回None,如果你自己寫了return None,
      也是一樣的效果,不會中斷你的請求,但是如果你return 的一個httpresponse對象,
      那么就會在這個方法中斷你的請求,直接返回給用戶,這就成了非正常的流程了
#并且,如果你在這里return了httpresponse對象,那么會從你這個中間件類中的
      process_response方法開始執行返回操作,所以這個類里面只要有process_response方法,
      肯定會執行def process_response(self,request,response):print("Md1返回")return responseclass Md2(MiddlewareMixin):def process_request(self,request):print("Md2請求")
def process_response(self,request,response):print("Md2返回")return response

  結果為:

Md1請求 Md1返回

  流程圖如下:

?

?    實例: 訪問白名單設置

class M1(MiddlewareMixin):def process_request(self,request):#設置路徑白名單,只要訪問的是login登陸路徑,就不做這個cookie認證if request.path not in [reverse('login'),]:print('我是M1中間件') #客戶端IP地址# return HttpResponse('sorry,沒有通過我的M1中間件')is_login = request.COOKIES.get('is_login', False)if is_login:passelse:# return render(request,'login.html')return redirect(reverse('login'))else:return None #別忘了return Nonedef process_response(self,request,response):print('M1響應部分')# print(response.__dict__['_container'][0].decode('utf-8'))return response# return HttpResponse('瞎搞')

?

  3. process_view

?

process_view(self, request, view_func, view_args, view_kwargs)該方法有四個參數request是HttpRequest對象。view_func是Django即將使用的視圖函數。 (
            它是實際的函數對象,而不是函數的名稱作為字符串。)view_args是將傳遞給視圖的位置參數的列表.view_kwargs是將傳遞給視圖的關鍵字參數的字典。
            view_args和view_kwargs都不包含第一個視圖參數(request)。Django會在調用視圖函數之前,路由匹配之后(process_request方法之后)調用process_view方法。

?

  ① 流程圖

?

?  ② 示例:(訪問index視圖函數)

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD1 中的process_view")print(view_func, view_func.__name__) #就是url映射到的那個視圖函數,
          也就是說每個中間件的這個process_view已經提前拿到了要執行的那個視圖函數
#ret = view_func(request) #提前執行視圖函數,不用到了上圖的試圖函數的位置再執行,
          如果你視圖函數有參數的話,可以這么寫 view_func(request,view_args,view_kwargs)
#return ret #直接就在MD1中間件這里這個類的process_response給返回了,
            就不會去找到視圖函數里面的這個函數去執行了。class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")passdef process_response(self, request, response):print("MD2里面的 process_response")return responsedef process_view(self, request, view_func, view_args, view_kwargs):print("-" * 80)print("MD2 中的process_view")print(view_func, view_func.__name__)

  結果:

MD1里面的 process_request MD2里面的 process_request -------------------------------------------------------------------------------- MD1 中的process_view <function index at 0x000001DE68317488> index -------------------------------------------------------------------------------- MD2 中的process_view <function index at 0x000001DE68317488> index app01 中的 index視圖 MD2里面的 process_response MD1里面的 process_response

  ③寫了返回對象的情況

?

?

返回值是HttpResponse:當前中間件之后的中間的process_view方法和視圖函數都不執行,直接執行最后一個中間件的process_reponse方法.

?

?

?

  4.process_exception

process_exception(self, request, exception)該方法兩個參數:一個HttpRequest對象一個exception是視圖函數異常產生的Exception對象。這個方法只有在視圖函數中出現異常了才執行,

它返回的值可以是一個None也可以是一個HttpResponse對象。如果是HttpResponse對象,

Django將調用模板和中間件中的process_response方法,并返回給瀏覽器,否則將默認處理異常。

如果返回一個None,則交給下一個中間件的process_exception方法來處理異常。

它的執行順序也是按照中間件注冊順序的倒序執行。

?

?  ①示例1:

from django.utils.deprecation import MiddlewareMixinclass MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef 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")class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")passdef process_response(self, request, response):print("MD2里面的 process_response")return responsedef 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")

  流程圖:

?

?

?  ②示例2:在process_exception中返回一個響應對象

class MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")def process_response(self, request, response):print("MD2里面的 process_response")return responsedef 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")return HttpResponse(str(exception)) # 返回一個響應對象

?

?  結果:

?

MD1里面的 process_request MD2里面的 process_request -------------------------------------------------------------------------------- MD1 中的process_view <function index at 0x0000022C09727488> index -------------------------------------------------------------------------------- MD2 中的process_view <function index at 0x0000022C09727488> index app01 中的 index視圖 呵呵 MD2 中的process_exception MD2里面的 process_response MD1里面的 process_response

  流程圖:

?

返回None:正常流程.返回HttpResponse對象:后面的中間件的process_view方法不執行,直接執行最后一個中間件的process_response方法.

?

process_template_response(用的比較少)

process_template_response(self, request, response)

它的參數,一個HttpRequest對象,response是TemplateResponse對象(由視圖函數或者中間件產生)。

process_template_response是在視圖函數執行完成后立即執行,但是它有一個前提條件,那就是視圖函數返回的對象有一個render()方法(或者表明該對象是一個TemplateResponse對象或等價方法)。

class MD1(MiddlewareMixin):def process_request(self, request):print("MD1里面的 process_request")def process_response(self, request, response):print("MD1里面的 process_response")return responsedef 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 responseclass MD2(MiddlewareMixin):def process_request(self, request):print("MD2里面的 process_request")def process_response(self, request, response):print("MD2里面的 process_response")return responsedef 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 = renderreturn rep

訪問index視圖,終端輸出的結果:

MD2里面的 process_request MD1里面的 process_request -------------------------------------------------------------------------------- MD2 中的process_view <function index at 0x000001C111B97488> index -------------------------------------------------------------------------------- MD1 中的process_view <function index at 0x000001C111B97488> index app01 中的 index視圖 MD1 中的process_template_response MD2 中的process_template_response in index/render MD1里面的 process_response MD2里面的 process_response

從結果看出:

視圖函數執行完之后,立即執行了中間件的process_template_response方法,順序是倒序,先執行MD1的,在執行MD2的,接著執行了視圖函數返回的HttpResponse對象的render方法,返回了一個新的HttpResponse對象,接著執行中間件的process_response方法。

?

?

?補充:? 登錄時瀏覽器自動加? "/"

  ①在輸入時

?

?  ②瀏覽器自動加 '/'

?

?

?  ③在一些情況下不需要加時,

在settings.py文件中進行設置

?

?

轉載于:https://www.cnblogs.com/lw1095950124/p/10499985.html

總結

以上是生活随笔為你收集整理的day62 中间件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。