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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Django 2.0 学习(20):Django 中间件详解

發布時間:2023/12/10 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django 2.0 学习(20):Django 中间件详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Django 中間件詳解

Django中間件

在Django中,中間件(middleware)其實就是一個類,在請求到來和結束后,Django會根據自己的規則在合適的時機執行中間件中相應的方法。

  • 1.執行完所有的request方法到達執行流程;
  • 2.執行中間件的其他方法;
  • 3.經過所有response方法,返回客戶端;

注意:如果在其中任意中間件中request方法return了值,就會執行當前中間件的response方法,返回給用戶,然后拋出錯誤,不會再執行下一個中間件。

Django 1.9版本之前,如果在request方法中遇到return,會執行最后一個中間件的response方法,然后依次回傳。

中間件(類)中5種方法

中間件種可以定義5個方法,分別是:

  • process_request(self, request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_template_response(self, request, response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

1.process_request(self, request),process_response(self, request, response)
當用戶發起請求的時候會依次經過所有的中間件,這個時候的請求是process_request,最后到達views函數中,views函數處理后,再依次穿過中間件,這個時候是process_response,最后返回給請求者,在Django中叫做中間件,在其他web框架中,有的叫管道或httphandle

上述截圖中的中間件都是Django中的,我們也可以定義自己的中間件,自己寫一個類(但是必須繼承MiddlewareMixin),下文會對自定義中間件進行詳細介紹。

2.process_view(self, request, callback, callback_args, callback_kwargs)

  • 執行完所有中間件的request方法
  • url匹配成功
  • 拿到試圖函數的名稱、參數(注意不執行),再執行process_view()方法
  • 最后去執行視圖函數

練習 1

from django.utils.deprecation import MiddlewareMixinclass M1(MiddlewareMixin):def process_request(self, request):print("M1.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M1.process_view")def process_response(self, request, response):print("M1.response")return responseclass M2(MiddlewareMixin):def process_request(self, request):print("M2.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M2.process_view")def process_response(self, request, response):print("M2.response")return response

執行結果為:

練習 2
既然process_view拿到視圖函數的名稱、參數(不執行),再執行process_view()方法,最后才去執行視圖函數。那么在執行process_view環節,可以直接把函數執行返回嗎?

from django.utils.deprecation import MiddlewareMixinclass M1(MiddlewareMixin):def process_request(self, request):print("M1.request")# callback視圖函數名稱,callback_args,callback_kwargs視圖函數執行所需要的參數def process_view(self, request, callback, callback_args, callback_kwargs):print("M1.process_view")response = callback(request, *callback_args, **callback_kwargs)return responsedef process_response(self, request, response):print("M1.response")return responseclass M2(MiddlewareMixin):def process_request(self, request):print("M2.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M2.process_view")def process_response(self, request, response):print("M2.response")return response

執行結果為:

結論:如果process_view函數有返回值,跳轉到最后一個中間件,執行最后一個中間件的response方法,逐步返回。和process_request方法不一樣,request方法在當前中間件的response方法返回。其過程分析圖如下:

3.process_exception(self, request, exception)

from django.utils.deprecation import MiddlewareMixinclass M1(MiddlewareMixin):def process_request(self, request):print("M1.request")# callback視圖函數名稱,callback_args,callback_kwargs視圖函數執行所需要的參數def process_view(self, request, callback, callback_args, callback_kwargs):print("M1.process_view")# response = callback(request, *callback_args, **callback_kwargs)# return responsedef process_response(self, request, response):print("M1.response")return responsedef process_exception(self, request, exception):print("M1.exception")class M2(MiddlewareMixin):def process_request(self, request):print("M2.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M2.process_view")def process_response(self, request, response):print("M2.response")return responsedef process_exception(self, request, exception):print("M2.exception")

process_exception默認不執行,所以添加process_exception方法,啥也沒執行

process_exception方法只有在視圖函數執行出錯的時候才會執行

M1.request M2.request M1.process_view M2.process_view 執行index M2的process_exception M1的process_exception Internal Server Error: /index/ Traceback (most recent call last):File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\exception.py", line 41, in innerresponse = get_response(request)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 187, in _get_responseresponse = self.process_exception_by_middleware(e, request)File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 185, in _get_responseresponse = wrapped_callback(request, *callback_args, **callback_kwargs)File "F:\untitled1\app01\views.py", line 7, in indexint("ok") ValueError: invalid literal for int() with base 10: 'ok' M2.response M1.response [02/Jul/2018 16:43:59] "GET /index/ HTTP/1.1" 500 62663

1.執行完所有request方法;
2.執行所有process_view方法;
3.如果視圖函數出錯,執行process_exception(最終response,process_exception的return值),如果process_exception方法有了返回值就不再執行其他中間件的process_exception,直接執行response方法響應;
4.執行所有response方法;
5.最后返回process_exception的返回值;

process_exception應用:在視圖函數執行出錯時,返回錯誤信息。這樣頁面就不會報錯了:

from django.utils.deprecation import MiddlewareMixin from django.http import HttpResponseclass M1(MiddlewareMixin):def process_request(self, request):print("M1.request")# callback視圖函數名稱,callback_args,callback_kwargs視圖函數執行所需要的參數def process_view(self, request, callback, callback_args, callback_kwargs):print("M1.process_view")# response = callback(request, *callback_args, **callback_kwargs)# return responsedef process_response(self, request, response):print("M1.response")return responsedef process_exception(self, request, exception):print("M1.exception")class M2(MiddlewareMixin):def process_request(self, request):print("M2.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M2.process_view")def process_response(self, request, response):print("M2.response")return responsedef process_exception(self, request, exception):print("M2.exception")return HttpResponse("出錯了!!")

其過程分析如下圖所示:

4.process_template_response(self, request, response)

from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponseclass M1(MiddlewareMixin):def process_request(self, request):print("M1.request")# callback視圖函數名稱,callback_args,callback_kwargs視圖函數執行所需要的參數def process_view(self, request, callback, callback_args, callback_kwargs):print("M1.process_view")# response = callback(request, *callback_args, **callback_kwargs)# return responsedef process_response(self, request, response):print("M1.response")return responsedef process_exception(self, request, exception):print("M1.exception")class M2(MiddlewareMixin):def process_request(self, request):print("M2.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M2.process_view")def process_response(self, request, response):print("M2.response")return responsedef process_exception(self, request, exception):print("M2.exception")return HttpResponse("出錯了!!")def process_template_response(self, request, response):print("M2.process_template_response")return response

process_template_response方法默認不執行

process_template_response方法特性:只有在試圖函數的返回對象中有render方法才會執行,并把對象的render方法的返回值返回給用戶(注意:不返回試圖函數的return結果了,而是返回視圖函數return值(對象)的render方法)

class M2(MiddlewareMixin):def process_request(self, request):print("M2.request")def process_view(self, request, callback, callback_args, callback_kwargs):print("M2.process_view")def process_response(self, request, response):print("M2.response")return responsedef process_exception(self, request, exception):print("M2.exception")return HttpResponse("出錯了!!")def process_template_response(self, request, response):# 如果試圖函數中的返回值中有render方法,才會執行process_template_responseprint("M2.process_template_response")return response

視圖函數(views.py)

from django.shortcuts import render,HttpResponse# Create your views here. class Foo():def __init__(self,requ):self.req=requdef render(self):return HttpResponse('OKKKK')def index(request):print("執行index")obj=Foo(request)return obj

執行結果為:

應用:
既然process_template_response不返回視圖函數的return的結果,而是返回視圖函數return(對象)的render方法(多加了一個環節)。就可以在這個視圖函數返回對象的render方法里,做返回值的二次加工。多加工幾個,視圖函數就可以隨便使用了(好比噴霧器有了多個噴頭,換不同的噴頭出不同的水,返回值就可以組件化了)

from django.shortcuts import render,HttpResponse# Create your views here. class Dict(): #對視圖函數返回值做二次封裝 !!def __init__(self,requ,msg):self.req=requ self.msg=msgdef render(self):a=self.msg #在render方法里面 把視圖函數的 返回值 制作成字典 、列表等。。。 # 如果新增了其他 一個視圖函數直接,return對象 即可!不用每個視圖函數都寫 制作字典 列表 拼接的邏輯了return HttpResponse(a) #def index(request):print("執行index")obj=Dict(request,"vv")return obj

自定義中間件

1.在項目文件下創建Middle文件夾,并在該文件夾下面創建custom_middle.py文件,該文件代碼如下:

from django.utils.deprecation import MiddlewareMixin class Middle1(MiddlewareMixin):def process_request(self,request):print("來了")def process_response(self, request,response):print('走了')

2.在settings.py文件中,注冊該中間件(Django項目中的settings模塊中,有一個MIDDLEWARE_CLASSES變量,其中每個元素都是一個中間件)

執行結果為

為什么結果報錯了??這是因為自定義的中間件response方法沒有return,交給下一個中間件,導致http請求中斷了!注意:自定義的中間件request方法不要return,因為返回值中間件不再往下執行,導致http請求到達不了視圖層,因為request在視圖之前執行。

from django.utils.deprecation import MiddlewareMixin class Middle1(MiddlewareMixin):def process_request(self,request):print("來了") # 不用return Django內部自動幫我們傳遞def process_response(self, request,response):print('走了')return response # 執行完了這個中間件一定要 傳遞給下一個中間件

**執行結果為

中間件應用場景

由于中間件工作在視圖函數執行前、執行后(就像所有視圖函數的裝飾器),適合所有的請求/一部分請求做批處理,其應用主要有:

  • 1.IP限制:放在中間件類的列表中,組織某些IP訪問;
  • 2.URL訪問過濾:如果用戶訪問的是login視圖(放過),如果訪問其他視圖(需要檢測是不是有session,有則放過;否則返回login),這樣省得在多個視圖函數上面寫裝飾器;
  • 3.緩存(CDN):客戶端請求來了,中間件去緩存看看有沒有數據,有直接返回給用戶,沒有再去邏輯層執行視圖函數;

轉載于:https://www.cnblogs.com/love9527/p/9239318.html

總結

以上是生活随笔為你收集整理的Django 2.0 学习(20):Django 中间件详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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