码迷,mamicode.com
首页 > 其他好文 > 详细

中间件

时间:2018-11-15 00:09:20      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:情况下   pytho   传递   一点   event   one   closed   除了   isp   

一、介绍
官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。

说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。

我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下图的MIDDLEWARE配置项。

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,
]



二、中间件的使用
1、 作用
    全局改变Django的请求和响应

2、 Django中自定义中间件
    1.新建一个python page包,包内新建py文件
      在py文件内定义中间件
      示例:
    from django.utils.deprecation import MiddlewareMixin

    class MD1(MiddlewareMixin):

        def process_request(self, request):
            print("MD1里面的 process_request")

        def process_response(self, request, response):
            print("MD1里面的 process_response")
            return response

     然后去settings.py里面注册MIDDLEWARE

    2.五个方法(执行的时间点、执行的顺序、参数、返回值)
   1. process_request(self,request)             *****
        0. 执行的时间点:
            请求进来之后
        1. 执行顺序:
            按照中间件的注册顺序执行
        2. 参数
            当前请求对象(从哪个url进来的,request在中间件和views函数中都是那个url的request)
        3. 返回值
            1. 返回None继续执行后续的
            2. 返回响应对象,不继续执行后续的流程,直接返回响应

    2. process_response(self, request, response) *****
        0. 执行的时间点:
            返回响应之后(即经过了views.py里面的函数之后)
        1. 执行顺序:
            按照中间件注册的倒序执行
        2. 参数
            1. request:当前的请求对象
            2. response: 从views.py对应的函数中传递过来的响应对象
        3. 返回值:
            1. 必须返回一个响应对象

    3. process_view(self, request, view_func, view_args, view_kwargs)
        0. 执行的时间点:
            process_request之后,视图函数之前执行
        1. 执行顺序
            按照注册的顺序执行
        2. 参数
            1. request:请求对象
            2. view_func: 将要执行的视图函数对象
            3. view_args/view_kwargs: 将要执行的函数的参数
        3. 返回值
            1. None:继续往后执行
            2. 响应对象: 直接返回了,不会执行后续的视图函数
    
    4. process_template_response(self,request,response)
        0. 执行的时间点
            当视图函数中返回带render方法的响应对象,这个方法才会执行
        1. 执行顺序:
            注册的倒序
        2. 参数:
            1. request:请求对象
            2. response:响应对象
        3. 返回值
            1. 必须返回响应对象    

    5. process_exception(self, request, exception)
        0. 执行的时间点
            当视图函数中抛出异常的时候才会执行这个方法
        1. 执行顺序:    
            注册的倒序
        2. 参数:
            1. request:请求对象
            2. exception: 视图函数抛出的异常
        3. 返回值:
            1. None:继续执行后续
            2. 响应对象: 直接返回


3、例子
1.process_request(self, request) 
技术分享图片
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M1 process_request)
        # return HttpResponse(‘ok‘)


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M2 process_request)
View Code


2.process_response(self, request, response)
技术分享图片
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M1 process_request)
        # return HttpResponse(‘ok‘)

    def process_response(self, request, response):
        print(in M1 process_response)
        return response  # 必须返回一个对象


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M2 process_request)

    def process_response(self, request, response):
        print(in M2 process_response)
        return response  # 必须返回一个对象
View Code


3.process_view(self, request, view_func, view_args, view_kwargs)
技术分享图片
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M1 process_request)
        # return HttpResponse(‘ok‘)

    def process_response(self, request, response):
        print(in M1 process_response)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        # view_func(request)  # 在中间件中手动调用将要执行的视图函数
        print(这是M1里面的process_view方法)
        # return HttpResponse(‘OJ8K‘)


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M2 process_request)

    def process_response(self, request, response):
        print(in M2 process_response)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(这是M2里面的process_view方法)
View Code


4.process_template_response(self,request,response)
views.py
技术分享图片
def test(request):
    print(request, id(request))
    print(-------------in test--------------------------------------)
    rep = HttpResponse(我是原本的响应)
    def render():
        return HttpResponse(我有render方法啦,记住是方法!)
    rep.render = render  # 给响应对象设置一个属性render,给这个属性添加render方法
    return rep
View Code


中间件
技术分享图片
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M1 process_request)
        # return HttpResponse(‘ok‘)

    def process_response(self, request, response):
        print(in M1 process_response)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(这是M1里面的process_view方法)
        # return HttpResponse(‘OJ8K‘)

    def process_template_response(self, request, response):
        print(这是M1中process_template_response方法)
        return(response)  # 必须要有响应对象


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M2 process_request)

    def process_response(self, request, response):
        print(in M2 process_response)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(这是M2里面的process_view方法)
View Code


5.process_exception(self, request, exception)
views.py
技术分享图片
def test(request):
    print(request, id(request))
    print(-------------in test--------------------------------------)
    raise ValueError(英雄联盟)
    return HttpResponse(我是test视图函数)
View Code



中间件
技术分享图片
class M1(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M1 process_request)
        # return HttpResponse(‘ok‘)

    def process_response(self, request, response):
        print(in M1 process_response)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(这是M1里面的process_view方法)
        # return HttpResponse(‘OJ8K‘)

    def process_template_response(self, request, response):
        print(这是M1中process_template_response方法)
        return(response)

    def process_exception(self, request, exception):
        print(这是M1中的process_exception)
        print(exception)
        return HttpResponse(视图函数报错啦!)


class M2(MiddlewareMixin):
    def process_request(self, request):
        print(request, id(request))
        print(in M2 process_request)

    def process_response(self, request, response):
        print(in M2 process_response)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print(view_func)
        print(这是M2里面的process_view方法)

    def process_exception(self, request, exception):
        print(这是M2中的process_exception)
View Code



三、中间件的流程图
1、django框架完整流程图
技术分享图片
2、process_request和process_response 当process_request没有返回响应对象的时候,会继续执行后面的操作,顺利执行完后,会执行视图函数,最后执行process_response, 当process_request返回了响应对象,那么它会立刻执行自己的process_response方法, 此时process_response中的response参数接收的是process_request返回的响应对象 技术分享图片 3、process_request和process_response和process_view 当process_request没有返回响应对象的时候,会继续执行后面的process_request操作, 当process_request返回了响应对象,那么它会立刻执行自己的process_response方法, 此时process_response中的response参数接收的是process_request返回的响应对象, 当process_request没有返回响应对象,顺利执行完后,将会执行process_view, 当process_view没有返回响应对象的时候,会继续执行后面的process_view操作,顺利执行完后,会执行视图函数,最后执行process_response, 当process_view返回了一个响应对象的时候,后续操作(除了process_response)将不会执行, 而是把响应对象返回给最后一个process_response方法。 技术分享图片 4、总结 请求进来的时候,按顺序执行process_request,然后执行process_view,执行完后,再执行views.py里面的视图函数,最后按倒叙执行process_response, process_response无论如何都是会执行的,它是做响应处理,然后把响应返回给浏览器的函数, 当process_request返回了一个响应对象的时候,后续操作(除了process_response)将不会执行,而是直接把响应对象返回给自己的process_response方法, 当process_view返回了一个响应对象的时候,后续操作(除了process_response)将不会执行,而是把响应对象返回给最后一个process_response方法。
技术分享图片 注意: 一般情况下是process_response做响应处理。 当视图函数中返回带render方法的响应对象时,执行process_template_response做响应处理,然后process_template_response会把响应再返回给process_response做最后的响应处理。 当视图函数中抛出异常的时候,执行process_exception做响应处理,然后process_exception会把响应再返回给process_response做最后的响应处理。
技术分享图片

 

中间件

标签:情况下   pytho   传递   一点   event   one   closed   除了   isp   

原文地址:https://www.cnblogs.com/Zzbj/p/9961004.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!