ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

​Django边学边记——中间件​

2021-09-21 18:04:39  阅读:161  来源: 互联网

标签:__ get 中间件 self request 边学边 Django response


特点

Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,用于全局修改Django的输入或输出。

每个中间件组件负责做一些特定的功能。中间件全部注册在setting.py中的 MIDDLEWARE 列表中。

中间件是可调用的,它接受请求并返回响应,就像视图一样。

为了在于不同的阶段执行,对输入或输出进行干预,我们可以编写自己的中间件。

使用

1.在项目中创建一个中间件包>创建中间件py文件 

 

2.编写中间件程序代码

一般习惯于将中间件写成一个类 :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class SimpleMiddleware:

    def __init__(self, get_response):

        self.get_response = get_response

        # 服务器启动时 调用一次写在这里的代码

    def __call__(self, request):

        # 处理请求之前  执行写在这里的代码,相当于老版本的 process_request(request)

        response = self.get_response(request)

        # 视图处理后,返回浏览器前 执行这里的代码 相当于老版本的 process_response(request,response)

  

        return response

     

    def process_view(self,request,view_func,*args,**kwargs):

        # 处理请求后,处理视图前,执行这里的代码

        # 返回None或HttpResponse对象

        pass  

每个自定义的中间件类 必须有_init__ 和 __call__ 两个方法,写法也比较固定。一般按照文档说明中的格式套用即可,只需在相应位置加上自己的控制代码。

get_response参数是必需的,这个参数指的是下一个中间件或者view函数(如果是最后一个中间件)。

中间件也可以被写成这样的函数(习惯用类):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

def simple_middleware(get_response):

    # One-time configuration and initialization.

    def middleware(request):

        # Code to be executed for each request before

        # the view (and later middleware) are called.

        response = get_response(request)

        # Code to be executed for each request/response after

        # the view is called.

        return response

    return middleware

3. 注册中间件模块

在项目setting.py 的MIDDLEWEAR列表 中注册自定义中间件模块

1

2

3

4

5

6

7

8

9

10

MIDDLEWARE = [

    'django.middleware.security.SecurityMiddleware',

    'django.contrib.sessions.middleware.SessionMiddleware',

    'django.middleware.common.CommonMiddleware',

    'django.middleware.csrf.CsrfViewMiddleware',

    'django.contrib.auth.middleware.AuthenticationMiddleware',

    'django.contrib.messages.middleware.MessageMiddleware',

    'django.middleware.clickjacking.XFrameOptionsMiddleware',

    'test.middleware.middleware.MyMd',

]

  

中间件顺序与分层

在请求阶段,在调用视图之前,Django 按照定义的顺序应用中间件 MIDDLEWARE,自顶向下。

你可以把它想象成一个多道门的房子:每个中间件类都是一个“门”,视图在房子的最中间。如果请求通过所有门(每一个调用 get_response )到达房子最中间的视图,那么响应将在返回的过程中也要通过进来的所有门出去(以相反的顺序)。

如果其中一道门决定不让进,并返回响应而不调用get_response,那么这道门后面的门都不会看到请求或响应。响应将只通过请求传入的相同层返回。 

经典流程图如下:

其他中间件钩子

除前面讲到的,还有2种会用到的中间件方法:

1.异常处理:当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象

1

2

def process_exception(request,exception):

    pass

2.处理模板响应前:在每个请求上调用,返回实现了render方法的响应对象

1

2

def process_template_response(request, response):

    pass

实例应用

1.实现每个IP向 /pw 开头的地址 最多请求5次

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class LimitIp:

    ip_dict = {}

    def __init__(self, get_response):

        self.get_response = get_response

    def __call__(self, request):

        tar_ip = request.META['REMOTE_ADDR']

        if request.path_info.startswith('/pw'):           

          count = self.ip_dict.get(tar_ip, 0)

          count += 1

          self.ip_dict[tar_ip] = count

          if count > 5:

              return HttpResponse(f'你已经访问{count}次,超出访问限制')

        response = self.get_response(request)

        return response

  

2.实现让有权限的管理员可以在DEBUG关闭的情况下看到错误信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import sys

  

from django.views.debug import technical_500_response

  

class ExceptionMiddleware(object):

    def __init__(self, get_response):

        self.get_response = get_response

  

    def __call__(self, request):

        response = self.get_response(request)

        return response

  

    def process_exception(self, request, exception):

        if request.user.is_admin:

            return technical_500_response(request, *sys.exc_info())

  

标签:__,get,中间件,self,request,边学边,Django,response
来源: https://blog.csdn.net/m0_60148758/article/details/120403851

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有