Django進階之中間件

?

中間件簡介

在http請求 到達視圖函數之前 ? 和視圖函數return之后,django會根據自己的規則在合適的時機執行中間件中相應的方法。

?

中間件的執行流程

1、執行完所有的request方法 到達視圖函數。

2、執行中間件的其他方法

2、經過所有response方法 返回客戶端。

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

?

自定義中間件?

1、在porject下創建自定義py文件

1 from django.utils.deprecation import MiddlewareMixin
2 class Middle1(MiddlewareMixin):
3     def process_request(self,request):
4         print("來了")
5     def process_response(self, request,response):
6         print('走了')
View Code

2、在setings文件中注冊這個py文件

django項目的settings模塊中,有一個 MIDDLEWARE_CLASSES?變量,其中每一個元素就是一個中間件

?

 1 MIDDLEWARE = [
 2     'django.middleware.security.SecurityMiddleware',
 3     'django.contrib.sessions.middleware.SessionMiddleware',
 4     'django.middleware.common.CommonMiddleware',
 5     'django.middleware.csrf.CsrfViewMiddleware',
 6     'django.contrib.auth.middleware.AuthenticationMiddleware',
 7     'django.contrib.messages.middleware.MessageMiddleware',
 8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 9     'M1.Middle1',
10 ]
View Code

執行結果:

為啥報錯了呢?

因為 自定義的中間件response方法沒有return,交給下一個中間件,導致http請求中斷了!!!

注意?自定義的中間件request 方法不要return ?因為返回值中間件不再往下執行,導致 http請求到達不了視圖層,因為request在視圖之前執行!

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

中間件(類)中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_view(self, request, callback, callback_args, callback_kwargs)方法介紹

(1)執行完所有中間件的request方法‘

(2)url匹配成功

(3)拿到 視圖函數的名稱、參數,(注意不執行) 再執行process_view()方法

(4)最后去執行視圖函數

常規使用方法:

 1 from  django.utils.deprecation import MiddlewareMixin
 2 
 3 
 4 class M1(MiddlewareMixin):
 5     def process_request(self, request):
 6         print('M1.request') 
 7 
 8     def process_view(self, request,callback,callback_args,callback_kwargs ):
 9         print("M1.process_view")
10      
11     def process_response(self, request, response):
12         print('M1.response')
13         return response 
14 
15 
16 
17 class M2(MiddlewareMixin):
18     def process_request(self, request):
19         print('M2.request') 
20 
21     def process_view(self, request,callback,callback_args,callback_kwargs ):
22         print("M2.process_view")
23   
24     def process_response(self, request, response):
25         print('M2.response')
26         return response
View Code

執行結果

使用方法2

既然 process_view 拿到視圖函數的名稱、參數,(不執行) 再執行process_view()方法,最后才去執行視圖函數!

那可以在 執行process_view環節直接 把函數執行返回嗎?

 1 from  django.utils.deprecation import MiddlewareMixin
 2 
 3 
 4 class M1(MiddlewareMixin):
 5     def process_request(self, request):
 6         print('M1.request')
 7                  # callback視圖函數名稱 callback_args,callback_kwargs 視圖函數執行所需的參數
 8     def process_view(self, request,callback,callback_args,callback_kwargs ):
 9         print("M1.process_view")
10         response=callback(request,*callback_args,**callback_kwargs)
11         return response
12     def process_response(self, request, response):
13         print('M1.response')
14         return response
15 
16 
17 
18 class M2(MiddlewareMixin):
19     def process_request(self, request):
20         print('M2.request')  
21 
22     def process_view(self, request,callback,callback_args,callback_kwargs ):
23         print("M2.process_view")
24     def process_response(self, request, response):
25         print('M2.response')
26         return response
View Code

執行結果

結論:

如果process_view函數有返回值,跳轉到最后一個中間件, 執行最后一個中間件的response方法,逐步返回。

和 process_request方法不一樣哦! ?request方法在當前中間件的response方法返回。

2、process_exception(self, request, exception)方法

這個方法只有在出現錯誤的時候才會觸發

加了process_exception方法 咋啥也沒執行呢?!!原來是process_exception默認不執行!!!

 1 from  django.utils.deprecation import MiddlewareMixin
 2 
 3 
 4 class M1(MiddlewareMixin):
 5     def process_request(self, request):
 6         print('M1.request')
 7         
 8     def process_view(self, request,callback,callback_args,callback_kwargs ):
 9         print("M1.process_view")
10 
11     def process_response(self, request, response):
12         print('M1.response')
13         return response
14 
15     def process_exception(self, request,exception):
16         print('M1的process_exception')
17 
18 
19 class M2(MiddlewareMixin):
20     def process_request(self, request):
21         print('M2.request') 
22 
23     def process_view(self, request,callback,callback_args,callback_kwargs ):
24         print("M2.process_view")
25 
26     def process_response(self, request, response):
27         print('M2.response')
28         return response
29 
30     def process_exception(self, request, exception):
31         print('M2的process_exception')
View Code

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

 1 M1.request
 2 M2.request
 3 M1.process_view
 4 M2.process_view
 5 執行index
 6 M2的process_exception
 7 M1的process_exception
 8 Internal Server Error: /index/
 9 Traceback (most recent call last):
10   File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
11     response = get_response(request)
12   File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
13     response = self.process_exception_by_middleware(e, request)
14   File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
15     response = wrapped_callback(request, *callback_args, **callback_kwargs)
16   File "F:\untitled1\app01\views.py", line 7, in index
17     int("ok")
18 ValueError: invalid literal for int() with base 10: 'ok'
19 M2.response
20 M1.response
21 [03/Jul/2017 16:43:59] "GET /index/ HTTP/1.1" 500 62663
View Code

1、執行完所有 request 方法?

2、執行 所有 process_view方法

3、如果視圖函數出錯,執行process_exception(最終response,process_exception的return值)

?如果process_exception 方法有了 返回值 就不再執行 其他中間件的 process_exception,直接執行response方法響應?

4.執行所有response方法

5.最后返回process_exception的返回值

1 M1.request
2 M2.request
3 M1.process_view
4 M2.process_view
5 執行index
6 M2的process_exception (有了return值,直接執行response)
7 M2.response
8 M1.response
View Code

process_exception的應用

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

 1 class M1(MiddlewareMixin):
 2     def process_request(self, request):
 3         print('M1.request')
 4 
 5     def process_view(self, request,callback,callback_args,callback_kwargs ):
 6         print("M1.process_view")
 7 
 8     def process_response(self, request, response):
 9         print('M1.response')
10         return response
11 
12     def process_exception(self, request,exception):
13         print('M1的process_exception')
14 
15 
16 class M2(MiddlewareMixin):
17     def process_request(self, request):
18         print('M2.request')
19 
20     def process_view(self, request,callback,callback_args,callback_kwargs ):
21         print("M2.process_view")
22 
23     def process_response(self, request, response):
24         print('M2.response')
25         return response
26 
27     def process_exception(self, request, exception):
28         print('M2的process_exception')
29         return HttpResponse('出錯了兄弟!!!')
View Code

?

3、process_template_response(self,request,response) 這個方法只有在返回對象中有render方法的時候才執行,如render_to_response('/index/')

 1 from  django.utils.deprecation import MiddlewareMixin
 2 from django.shortcuts import HttpResponse
 3 
 4 class M1(MiddlewareMixin):
 5     def process_request(self, request):
 6         print('M1.request')
 7 
 8     def process_view(self, request,callback,callback_args,callback_kwargs ):
 9         print("M1.process_view")
10 
11     def process_response(self, request, response):
12         print('M1.response')
13         return response
14 
15 
16     def process_exception(self, request,exception):
17         print('M1的process_exception')
18 
19 
20 class M2(MiddlewareMixin):
21     def process_request(self, request):
22         print('M2.request')
23 
24     def process_view(self, request,callback,callback_args,callback_kwargs ):
25         print("M2.process_view")
26 
27     def process_response(self, request, response):
28         print('M2.response')
29         return response
30 
31     def process_exception(self, request, exception):
32         print('M2的process_exception')
33 
34     def process_template_response(self,request,response):
35         print('M2process_template_response')
36         return response
View Code

process_template_response()默認不執行

rocess_template_response()特性

只有在視圖函數的返回對象中有render方法才會執行!

并把對象的render方法的返回值返回給用戶(注意不返回視圖函數的return的結果了,而是返回視圖函數 return值(對象)的render方法)

 1 from  django.utils.deprecation import MiddlewareMixin
 2 from django.shortcuts import HttpResponse
 3 
 4 
 5 class M1(MiddlewareMixin):
 6     def process_request(self, request):
 7         print('M1.request')
 8 
 9     def process_view(self, request,callback,callback_args,callback_kwargs ):
10         print("M1.process_view")
11 
12     def process_response(self, request, response):
13         print('M1.response')
14         return response
15 
16 
17     def process_exception(self, request,exception):
18         print('M1的process_exception')
19 
20 
21 class M2(MiddlewareMixin):
22     def process_request(self, request):
23         print('M2.request')
24 
25     def process_view(self, request,callback,callback_args,callback_kwargs ):
26         print("M2.process_view")
27 
28     def process_response(self, request, response):
29         print('M2.response')
30         return response
31 
32     def process_exception(self, request, exception):
33         print('M2的process_exception')
34 
35     def process_template_response(self,request,response):  #如果視圖函數中的返回值 中有render方法,才會執行 process_template_response
36         print('M2process_template_response')
37         return response
View Code

視圖函數

 1 from django.shortcuts import render,HttpResponse
 2 
 3 # Create your views here.
 4 class Foo():
 5     def __init__(self,requ):
 6         self.req=requ
 7     def render(self):
 8         return HttpResponse('OKKKK')
 9 
10 def index(request):
11     print("執行index")
12     obj=Foo(request)
13     return obj
View Code

執行結果:

?應用:

既然process_template_respnse,不返回視圖函數的return的結果,而是返回視圖函數 return值(對象)的render方法;(多加了一個環節)

?就可以在 這個視圖函數返回對象的 render方法里,做返回值的二次加工了!多加工幾個,視圖函數就可以隨便使用了!

(好比 噴霧器有了多個噴頭,換不同的噴頭噴出不同水,返回值就可以也組件化了)

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

?

中間件應用場景

由于中間件工作在 視圖函數執行前、執行后(像不像所有視圖函數的裝飾器!)適合所有的請求/一部分請求做批量處理

1、做IP限制

放在 中間件類的列表中,阻止某些IP訪問了;

2、URL訪問過濾

如果用戶訪問的是login視圖(放過)

如果訪問其他視圖(需要檢測是不是有session已經有了放行,沒有返回login),這樣就省得在 多個視圖函數上寫裝飾器了!

3、緩存(還記得CDN嗎?)

客戶端請求來了,中間件去緩存看看有沒有數據,有直接返回給用戶,沒有再去邏輯層 執行視圖函數

轉載于:https://www.cnblogs.com/wangshuyang/p/8744802.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389894.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389894.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389894.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

漢諾塔遞歸算法進階_進階python 1遞歸

漢諾塔遞歸算法進階When something is specified in terms of itself, it is called recursion. The recursion gives us a new idea of how to solve a kind of problem and this gives us insights into the nature of computation. Basically, many of computational artifa…

500. 鍵盤行

500. 鍵盤行 給你一個字符串數組 words ,只返回可以使用在 美式鍵盤 同一行的字母打印出來的單詞。鍵盤如下圖所示。 美式鍵盤 中: 第一行由字符 “qwertyuiop” 組成。 第二行由字符 “asdfghjkl” 組成。 第三行由字符 “zxcvbnm” 組成。 示例 1&a…

windows 停止nginx

1、查找進程 tasklist | findstr nginx2、殺死進程 taskkill /pid 6508 /F3、一次殺死多個進程taskkill /pid 6508 /pid 16048 /f轉載于:https://blog.51cto.com/dressame/2161759

SpringBoot返回json和xml

有些情況接口需要返回的是xml數據&#xff0c;在springboot中并不需要每次都轉換一下數據格式&#xff0c;只需做一些微調整即可。 新建一個springboot項目&#xff0c;加入依賴jackson-dataformat-xml&#xff0c;pom文件代碼如下&#xff1a; <?xml version"1.0&quo…

575. 分糖果

575. 分糖果 給定一個偶數長度的數組&#xff0c;其中不同的數字代表著不同種類的糖果&#xff0c;每一個數字代表一個糖果。你需要把這些糖果平均分給一個弟弟和一個妹妹。返回妹妹可以獲得的最大糖果的種類數。 示例 1:輸入: candies [1,1,2,2,3,3] 輸出: 3 解析: 一共有三…

如何開啟并配置CITRIX Xenserver的SNMP服務

以下博文轉載至虛擬人生Citrix Xenserver使用標準的NET-SNMP協議&#xff0c;關于NET-SNMP請參考www.net-snmp.org. Xenserver并沒有自己的MIB庫.Xenserver默認是禁止SNMP服務且并沒有開啟SNMP服務使用的端口,通過以下方式開啟并配置SNMP服務&#xff1a;1.編輯Xenserver的/etc…

orange 數據分析_使用Orange GUI的放置結果數據分析

orange 數據分析Objective : Analysing of several factors influencing the recruitment of students and extracting information through plots.目的&#xff1a;分析影響學生招生和通過情節提取信息的幾個因素。 Description : The following analysis presents the diffe…

C++(1)引用

引用 引用 為對象起另外一個名字&#xff0c;通過將聲明符寫成 &d&#xff0c;其中d是聲明的變量名。一旦初始化完成&#xff0c;引用將和起初始值綁定在一起&#xff0c;無法再綁定到另一個對象&#xff0c;因此引用必須初始化。 引用就是別名&#xff0c;初始化以后&am…

普里姆從不同頂點出發_來自三個不同聚類分析的三個不同教訓數據科學的頂點...

普里姆從不同頂點出發繪制大流行時期社區的風險群圖&#xff1a;以布宜諾斯艾利斯為例 (Map Risk Clusters of Neighbourhoods in the time of Pandemic: a case of Buenos Aires) 介紹 (Introduction) Every year is unique and particular. But, 2020 brought the world the …

一步一步圖文介紹SpriteKit使用TexturePacker導出的紋理集Altas

1、為什么要使用紋理集&#xff1f; 游戲是一種很耗費資源的應用&#xff0c;特別是在移動設備中的游戲&#xff0c;性能優化是非常重要的 紋理集是將多張小圖合成一張大圖&#xff0c;使用紋理集有以下優點&#xff1a; 1、減少內存占用&#xff0c;減少磁盤占用&#xff1b; …

BZOJ.1007.[HNOI2008]水平可見直線(凸殼 單調棧)

題目鏈接 可以看出我們是要維護一個下凸殼。 先對斜率從小到大排序。斜率最大、最小的直線是一定會保留的&#xff0c;因為這是凸殼最邊上的兩段。 維護一個單調棧&#xff0c;棧中為當前可見直線(按照斜率排序)。 當加入一條直線l時&#xff0c;可以發現 如果l與棧頂直線l的交…

荷蘭牛欄 荷蘭售價_荷蘭的公路貨運是如何發展的

荷蘭牛欄 荷蘭售價I spent hours daily driving on one of the busiest motorways in the Netherlands when commuting was still a norm. When I first came across with the goods vehicle data on CBS website, it immediately attracted my attention: it could answer tho…

Vim 行號的顯示與隱藏

2019獨角獸企業重金招聘Python工程師標準>>> Vim 行號的顯示與隱藏 一、當前文檔的顯示與隱藏 1 打開一個文檔 [rootpcname ~]# vim demo.txt This is the main Apache HTTP server configuration file. It contains the configuration directives that give the s…

結對項目-小學生四則運算系統網頁版項目報告

結對作業搭檔&#xff1a;童宇欣 本篇博客結構一覽&#xff1a; 1&#xff09;.前言(包括倉庫地址等項目信息) 2&#xff09;.開始前PSP展示 3&#xff09;.結對編程對接口的設計 4&#xff09;.計算模塊接口的設計與實現過程 5&#xff09;.計算模塊接口部分的性能改進 6&…

367. 有效的完全平方數

367. 有效的完全平方數 給定一個 正整數 num &#xff0c;編寫一個函數&#xff0c;如果 num 是一個完全平方數&#xff0c;則返回 true &#xff0c;否則返回 false 。 進階&#xff1a;不要 使用任何內置的庫函數&#xff0c;如 sqrt 。 示例 1&#xff1a;輸入&#xff1…

袁中的第三次作業

第一題&#xff1a; 輸出月份英文名 設計思路: 1:看題目&#xff1a;主函數與函數聲明&#xff0c;知道它要你干什么2&#xff1a;理解與分析&#xff1a;在main中&#xff0c;給你一個月份數字n&#xff0c;要求你通過調用函數char *getmonth&#xff0c;來判斷&#xff1a;若…

Python從菜鳥到高手(1):初識Python

1 Python簡介 1.1 什么是Python Python是一種面向對象的解釋型計算機程序設計語言&#xff0c;由荷蘭人吉多范羅蘇姆&#xff08;Guido van Rossum&#xff09;于1989年發明&#xff0c;第一個公開發行版發行于1991年。目前Python的最新發行版是Python3.6。 Python是純粹的自由…

如何成為數據科學家_成為數據科學家需要了解什么

如何成為數據科學家Data science is one of the new, emerging fields that has the power to extract useful trends and insights from both structured and unstructured data. It is an interdisciplinary field that uses scientific research, algorithms, and graphs to…

2053. 數組中第 K 個獨一無二的字符串

2053. 數組中第 K 個獨一無二的字符串 獨一無二的字符串 指的是在一個數組中只出現過 一次 的字符串。 給你一個字符串數組 arr 和一個整數 k &#xff0c;請你返回 arr 中第 k 個 獨一無二的字符串 。如果 少于 k 個獨一無二的字符串&#xff0c;那么返回 空字符串 “” 。 …

阿里云對數據可靠性保障的一些思考

背景互聯網時代的數據重要性不言而喻&#xff0c;任何數據的丟失都會給企事業單位、政府機關等造成無法計算和無法彌補的損失&#xff0c;尤其隨著云計算和大數據時代的到來&#xff0c;數據中心的規模日益增大&#xff0c;環境更加復雜&#xff0c;云上客戶群體越來越龐大&…