django 之 中间件

中间件

一、定义:

  中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。 每个中间件都会负责一个功能。

  django中的中间件(middleware),在django中,中间件其实就是一个类(继承MiddlewareMixin),在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
  在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,用于注册中间件,其中每一个元素就是一个中间件。
执行流程:
  我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:
  

  可以把中间件看作一层一层的过滤网,每层的类中都有处理不同问题的方法。也就是说,每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。

注意点:

  1.10版本的django直接在当前中间件中找到response返回;1.7或是1.8版本的,是跳到最后一个中间件找到response返回。

二、中间件的方法:(五个)

process_request(self,request)  
    #一般是没有返回值,请求报错:实质上就是中间件resquest返回的错误信息!
    #用于处理request请求,一般没有返回值。若是有return返回值,就不在向下执行,直接通过当前中间件类中的response方法,把结果返回给浏览器。
    #request执行,是在进行路由匹配,执行完之后,已经把所有路由系统中对应的视图函数全部读取。 
process_view(self, request, view_func, view_func_args, view_func_kwargs) 
	参数:
		- view_func ----> 视图函数的函数名
		- view_func_args, view_func_kwargs --->视图函数的参数。
  #request请求完了后,返回从头再开始执行第一个view直到最后一个view,
  #用于处理视图函数,中间件中没有返回执行的视图函数,则会顺序执行到最后一个然后执行视图函数;
  #如果某个中间件中返回值为直接调用视图函数,则会从当前这个中间件直接跳到视图函数文件去执行视图函数。然后再从response顺序返回(response都会执行)。
process_exception(self, request, exception)  #用于监测错误
	- 参数:exception ---> 出错之后,返回给页面的信息,就不再让页面报错!
process_response(self, request, response)  
    #返回给浏览器的响应信息,必须有返回值。    return response
	必须有返回值。return response
process_template_response(self,request,response) 
    #用于检测 视图函数中返回值,只有返回的是 render 才触发,其他类型不执行。

三、自定义中间件  

多执行几次,多推敲下执行顺序!

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
from django.utils.deprecation import MiddlewareMixin  #导入模块
from django.shortcuts import render,HttpResponse

class M1(MiddlewareMixin):
    def process_request(self,request):
        """
        已经完成了路由匹配
        :param request:
        :return:
        """
        print("m1.process_request")

        def process_view(self,request,callback,callback_args,callback_kwargs):
        """
        用于操作视图函数
        :param request:
        :param callback:
        :param callback_args:
        :param callback_kwargs:
        :return:
        """
    print("m1.process_view")
    print(callback) #查看执行的函数名字
    response=callback(request,*callback_args,**callback_kwargs)
    return response

    def process_exception(self, request, exception): #异常相关处理
        print("m1.process_exception")
        return HttpResponse("写错了!")
    #如果没有错误,直接执行response返回给客户端;
    # 若是有错误则执行exception处理异常(若某个中间件把异常处理了,就不再往下执行,直接跳转到最后一个中间件),
    # 然后返回到最后一个的中间件,再顺序执行response,返回给浏览器。

    def process_template_response(self,request,response):
        print("m1.process_template_response")
        #对视图函数的返回值有一定要求,视图函数返回中如果有render方法,才执行!
    #返回类的一个对象,对象内封装了多个方法,会默认执行render方法
    def process_response(self,request,response):
        """
        返回的响应信息
        :param request:
        :param response:
        :return:
        """
        print("m1.process_response")
        return response

class M2(MiddlewareMixin):
    def process_request(self,request):
        print("m2.process_request")

    def process_view(self,request,callback,callback_args,callback_kwargs):
        print("m2.process_view")

    def process_exception(self, request, exception): #异常相关处理
        print("m2.process_exception")

    def process_template_response(self, request, response):
        print("m2.process_template_response")

    def process_response(self,request,response):
        print("m2.process_response")
        return response        
中间件程序-->md.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',
    "md.M1",
    "md.M2",
    ]                    
settings.py 注册
from django.shortcuts import render,HttpResponse
import JSON
# Create your views here.

# def test(request):
#     print("test")
#     int("asss") #用于错误测试
#     return HttpResponse("....")

#用以测试中间件process_template_response方法
class JSONResponse:
    def __init__(self,req,status,msg):
        self.request = req
        self.status = status
        self.message = msg

    def reder(self):
        ret={
            "status":self.status,
            "message":self.message
            }
        return HttpResponse(JSON.dumps(ret))

def test(requset):
    return JSONResponse(requset,True,"错误信息")
views.py 视图函数

应用:对所有请求或一部分请求做批量处理

 

posted @ 2017-07-04 17:27  细雨蓝枫  阅读(204)  评论(0编辑  收藏  举报