Django之Middleware中間件方法使用


自定義中間件五個方法(部分方法)實例

自定義中間件項目:

  

 

模板Templates

  login.html 

 1 {% load static %}
 2 <!DOCTYPE html>
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <script src="{% static 'jquery-3.4.1.js' %}"></script>
 7     <script src="{% static 'jquery-cookie-1.4.1.js' %}"></script>
 8     <title>login</title>
 9 </head>
10 <body>
11 <div>
12     用戶名:<input type="text" id="username"><br>
13     密碼:<input type="password" id="password"><br>
14     {% csrf_token %}
15     <input type="button" id="submit" value="登錄">
16     <span id="warning" style="color: red;"></span>
17 </div>
18 </body>
19 <script>
20     $(function () {
21         $('#submit').click(function () {
22             
23             $.ajax({
24                 url:'{% url "login" %}',
25                 type:'post',
26                 headers:{'X-CSRFToken':$.cookie('csrftoken')},
27                 data:{
28                   username:$('#username').val(),
29                   password:$('#password').val(),
30  
31                 },
32                 success:function (response) {
33                     if (response.status){
34                         location.href=response.url
35                     }else {
36                         $('#warning').text('賬號或密碼有誤!')
37                     }
38                 }
39             })
40         })
41     })
42 </script>
43 </html>
login.html

  index.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>index</title>
 6 </head>
 7 <body>
 8 <div>
 9     <h1>這是主頁index,歡迎您的登錄!</h1>
10     <a href="{% url 'logout' %}"></a>
11 </div>
12 </body>
13 </html>
14  
index.html

控制器urls.py 

1 from django.conf.urls import url
2 from django.contrib import admin
3 from app01 import views
4 urlpatterns = [
5     url(r'^admin/', admin.site.urls),
6 url(r'^login/', views.login,name='login'),
7 url(r'^index/', views.index,name='index'),
8 url(r'^logout/', views.logout,name='logout'),
9 ]
urls.py

視圖views.py 

 1 from django.shortcuts import render,HttpResponse,redirect
 2 from django.urls import reverse
 3 import json
 4 from django.http import JsonResponse
 5  
 6 # Create your views here.
 7  
 8 def login(request):
 9     if request.method=='GET':
10         print('view視圖函數')
11         # raise ValueError    #視圖函數拋出異常時,才會逆序依次執行中自定義中間件中的process_exception方法
12         return  render(request,'login.html')
13     elif request.method=='POST':
14         name=request.POST.get('username')
15         psd=request.POST.get('password')
16         if name=='yang' and psd=='123':
17             request.session['status']=True
18             request.session['name']=name
19  
20             # return HttpResponse(json.dumps({'status':1,'url':reverse('index')}),content_type='application/json')
21             return JsonResponse({'status':1,'url':reverse('index')})
22         else:
23             return JsonResponse({'status':0,'url':''})
24  
25 def index(request):
26     return render(request,'index.html')
27  
28 def logout(request):
29     request.session.flush()#退出同時清空客戶端cookie和服務端session
30     return redirect('login')
views.py

自定義中間件middlewares.py

 1 #process_request和process_response兩個方法最常用
 2  
 3 from django.utils.deprecation import MiddlewareMixin
 4 from django.shortcuts import redirect,HttpResponse
 5 from django.urls import reverse
 6  
 7 class Middleware1(MiddlewareMixin):
 8     def process_request(self, request):
 9         print('M1_process_request:wsgi.py封裝socket和請求對象request之后,url控制器分發之前')
10         #設置白名單,在url列表中的請求均可不執行該中間件的以下代碼,直接繞過登錄認證
11         url = [reverse('login'), ]#請求白名單
12         if request.path in url:
13             return None
14         else:
15             if request.session.get('status'):
16                 pass
17             else:
18                 # 在process_request中,返回值只有為None時才會繼續執行后邊的中間件,否則直接返回當前process_request中return的內容
19                 return redirect('login')
20     def process_view(self, request, view_func, view_args, view_kwargs):
21         print('M1_process_view:控制器映射之后,視圖函數執行之前')
22     def process_exception(self, request, exception):
23         print('M1_process_exception:視圖函數中捕獲到錯誤時自動觸發該函數')
24     def process_response(self,request,response):
25         print('M1_process_response')
26         # 在process_response中,返回值只有為response對象時,才會接力式返回視圖函數的返回結果,否則會被process_response中的return結果覆蓋,不寫則報錯
27         return HttpResponse('M1_process_response:視圖函數執行之后,wsgi.py封裝send之前,返回值不是接力原視圖函數resopnse對象,而是被覆蓋')
28         # return response
29  
30 class Middleware2(MiddlewareMixin):
31     def process_request(self, request):
32         print('M2_process_request:wsgi.py封裝socket和請求對象request之后,url控制器分發之前')
33         #在process_request中,返回值只有為None時才會繼續執行后邊的中間件,否則直接返回當前process_request中return的內容
34         # return HttpResponse('M2_process_request返回不是None直接終止處理返回')
35     def process_view(self, request, view_func, view_args, view_kwargs):
36         print('M2_process_view:控制器映射之后,視圖函數執行之前')
37     def process_exception(self, request, exception):
38         print('M2_process_exception:視圖函數中捕獲到錯誤時自動觸發該函數')
39     def process_response(self,request,response):
40         print('M2_process_response')
41         return HttpResponse('M2_process_response:視圖函數執行之后,wsgi.py封裝send之前,返回值不是接力原視圖函數resopnse對象,而是被覆蓋')
42         # return response
middlewares.py

 

配置settings.py 

settings.py

 

 

 執行結果:

后端:

  

    前端:

    

   視圖函數拋出異常測試process_exception

    

中間件補充說明

process_template_response(用的比較少)

process_template_response(self, request, response)

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

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

 

 1 #中間件:
 2 class MD1(MiddlewareMixin):
 3  
 4     def process_request(self, request):
 5         print("MD1里面的 process_request")
 6  
 7     def process_response(self, request, response):
 8         print("MD1里面的 process_response")
 9         return response
10  
11     def process_view(self, request, view_func, view_args, view_kwargs):
12         print("-" * 80)
13         print("MD1 中的process_view")
14         print(view_func, view_func.__name__)
15  
16     def process_exception(self, request, exception):
17         print(exception)
18         print("MD1 中的process_exception")
19         return HttpResponse(str(exception))
20  
21     def process_template_response(self, request, response):
22         print("MD1 中的process_template_response")
23         return response
24  
25  
26 class MD2(MiddlewareMixin):
27     def process_request(self, request):
28         print("MD2里面的 process_request")
29         pass
30  
31     def process_response(self, request, response):
32         print("MD2里面的 process_response")
33         return response
34  
35     def process_view(self, request, view_func, view_args, view_kwargs):
36         print("-" * 80)
37         print("MD2 中的process_view")
38         print(view_func, view_func.__name__)
39  
40     def process_exception(self, request, exception):
41         print(exception)
42         print("MD2 中的process_exception")
43  
44     def process_template_response(self, request, response):
45         print("MD2 中的process_template_response")
46         return response
47  
48 views.py視圖:
49 def index(request):
50     print("app01 中的 index視圖")
51 #raise ValueError('出錯啦') 
52     def render():
53         print("in index/render")  
54         #raise ValueError('出錯啦') #至於render函數中報錯了,那么會先執行process_template_response方法,然后執行process_exception方法,如果是在render方法外面報錯了,那么就不會執行這個process_template_response方法了。
55         return HttpResponse("O98K") #返回的將是這個新的對象
56     rep = HttpResponse("OK")
57     rep.render = render
58 return rep
59  
60  
61 訪問index視圖,終端輸出的結果:
62 MD2里面的 process_request
63 MD1里面的 process_request
64 --------------------------------------------------------------------------------
65 MD2 中的process_view
66 <function index at 0x000001C111B97488> index
67 --------------------------------------------------------------------------------
68 MD1 中的process_view
69 <function index at 0x000001C111B97488> index
70 app01 中的 index視圖
71 MD2 中的process_template_response
72 MD1 中的process_template_response
73 in index/render
74 MD1里面的 process_response
75 MD2里面的 process_response
補充

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM