Django中Middleware中间件

1 Middleware中间件概述

	django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法。实际上当我们想在发起请求到服务器views处理函数,我们想对请求做一些提前处理,此时中间件就上场了。

django在settings模块中,有一个MIDDLEWARE_CLASSES变量,其中每一个元素就是一个中间件。
在settings.py文件中:
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',
    'django.middleware.DataConvert',
    '自定义中间件添加位置'
]

常见的middleware组件:
1. Sessions   	
2. Authentication 	
3. CSRF Protection 
4. GZipping Content

2 Middleware处理功能

在Djano中,中间件承担作用   Resquest---->Middleware ---->View----->Response
比如如果想实现接入安全验证,middleware是比较好的选择,是连接request与view的桥梁
Django中支持的中间件可以实现如下方法:

	方法名称			执行周期
	process_request		接受到request之后,但在确定View之前
	process_view		确定view之后,但真正执行view之前
	process_response	执行view之后
	process_exception	view抛出异常之后
	
详解: 每个请求都是先通过中间件process_request函数,这个函数返回None或者HttpResponse对象,返回前者继续处理其他中间件,返回HttpResponse,处理终止返回网页内容.每个中间件都是按照顺序依次进入处理程序.

3 自定义中间件Middleware

	我们网站放在服务器正式运行之后,DEBUG改为False,这样更加安全,但有时候发生错误不能显示错误详情页面,普通用户看到的是友好的报错信息,管理员看到的是错误详情,以便于修复BUG,为达到两者效果,利用middleware就能做到.下面我们看下我们定义的Middleware:
import sys
from django.views.debug import technical_500_response
from django.conf import settings

class UserBasedExceptionMiddleware(object):
   def process_exception(self, request, exception):
       if request.user.is_superuser or request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
           return technical_500_response(request, *sys.exc_info())
           
	在给大家展示一个有用的例子,我们都知道浏览器发送数据仅支持GET和POST两种请求方式,那我们是怎么实现PUT,DELETE,OPTIONS请求的功能的呢?  下面我们将展示采用中间件将request中的请求信息进行转化的方法:

PUT/DELETE/OPTIONS方法的转换中间件:

import json
from django.utils.deprecation import MiddlewareMixin
from django.http.multipartparser import MultiPartParser

class MethodConvertMiddleware(MiddlewareMixin):
    #创建请求处理函数
    def process_request(self,request):
        method = request.method
        #判断请求请求头信息中content-type是否含有application/json
            
        if 'application/json' in request.META['CONTENT_TYPE']:
            #json格式转Python字典
            data = json.loads(request.body.decode()
        #判断请求请求头信息中content-type是否含有mutipart/form-data
        
        elif 'mutipart/form-data' in request.META['CONTENT_TYPE']:
            #解析器解析出data与文件
            data,files = MultiPartParser(request.META,request,request.upload_handlers).parse()
        else:
            #这里不支持application/x-www-form-urlencoded,其余返回{}
            data = {}
            files = None
        #前段讲请求方式放在HTTP_X_METHOD
        if 'HTTP_X_METHOD' in request.META:
            method = request.META['HTTP_X_METHOD'].upper()
            #例如设定method = 'PUT'
            setattr(request,'method',method)
        if files:
            #files存在 request.PUT_FILES = files  数据data也设置给PUT,这样就转换过来了
            setattr(request,'{method}_FILES'.format(method=method),files)
        setattr(request,method,data)
        #中间件进入下一个处理程序
        return None
注:1  中间件没有添加异常处理程序,可自行添加.
   2  中间件只针对两种常见数据类型格式application/json 与 application/form-data.