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
补充

 

 

原文地址:https://www.cnblogs.com/open-yang/p/11222562.html