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.mzph.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…

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…

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…

普里姆从不同顶点出发_来自三个不同聚类分析的三个不同教训数据科学的顶点...

普里姆从不同顶点出发绘制大流行时期社区的风险群图&#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 …

荷兰牛栏 荷兰售价_荷兰的公路货运是如何发展的

荷兰牛栏 荷兰售价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&…

袁中的第三次作业

第一题&#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…

阿里云对数据可靠性保障的一些思考

背景互联网时代的数据重要性不言而喻&#xff0c;任何数据的丢失都会给企事业单位、政府机关等造成无法计算和无法弥补的损失&#xff0c;尤其随着云计算和大数据时代的到来&#xff0c;数据中心的规模日益增大&#xff0c;环境更加复杂&#xff0c;云上客户群体越来越庞大&…

linux实验二

南京信息工程大学实验报告 实验名称 linux 常用命令练习 实验日期 2018-4-4 得分指导教师 系 计软院 专业 软嵌 年级 2015 级 班次 &#xff08;1&#xff09; 姓名王江远 学号20151398006 一、实验目的 1. 掌握 linux 系统中 shell 的基础知识 2. 掌握 linux 系统中文件系统的…

个人项目api接口_5个免费有趣的API,可用于学习个人项目等

个人项目api接口Public APIs are awesome!公共API很棒&#xff01; There are over 50 pieces covering APIs on just the Towards Data Science publication, so I won’t go into too lengthy of an introduction. APIs basically let you interact with some tool or servi…

咕泡-模板方法 template method 设计模式笔记

2019独角兽企业重金招聘Python工程师标准>>> 模板方法模式&#xff08;Template Method&#xff09; 定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤Template Me…

如何评价强gis与弱gis_什么是gis的简化解释

如何评价强gis与弱gisTL;DR — A Geographic Information System is an information system that specializes in the storage, retrieval and display of location data.TL; DR — 地理信息系统 是专门从事位置数据的存储&#xff0c;检索和显示的信息系统。 The standard de…

Scrum冲刺-Ⅳ

第四次冲刺任务 团队分工 成员&#xff1a;刘鹏芝&#xff0c;罗樟&#xff0c;王小莉&#xff0c;沈兴艳&#xff0c;徐棒&#xff0c;彭康明&#xff0c;胡广键 产品用户&#xff1a;王小莉 需求规约&#xff1a;彭康明&#xff0c;罗樟 UML&#xff1a;刘鹏芝&#xff0c;沈…

机器人影视对接_机器学习对接会

机器人影视对接A simple question like ‘How do you find a compatible partner?’ is what pushed me to try to do this project in order to find a compatible partner for any person in a population, and the motive behind this blog post is to explain my approach…

mysql 数据库优化之执行计划(explain)简析

数据库优化是一个比较宽泛的概念&#xff0c;涵盖范围较广。大的层面涉及分布式主从、分库、分表等&#xff1b;小的层面包括连接池使用、复杂查询与简单查询的选择及是否在应用中做数据整合等&#xff1b;具体到sql语句执行效率则需调整相应查询字段&#xff0c;条件字段&…

自我接纳_接纳预测因子

自我接纳现实世界中的数据科学 (Data Science in the Real World) Students are often worried and unaware about their chances of admission to graduate school. This blog aims to help students in shortlisting universities with their profiles using ML model. The p…