django处理一个Request的过程是首先经过django 中间件,而后再经过默认的URL方式进行的。因此说咱们要作的就是在django 中间件这个地方把全部Request拦截住,用咱们本身的方式完成处理之后直接返回Response,那么咱们能够简化原来的设计思路,把中间件不能处理的 Request通通无论,丢给Django去处理。python
若是你要在用户登陆或者其它的处理过程当中完成本身的一些处理,好比进行权限控制,对返回结果做一些处理,可使用python的修饰器,但有个缺点就是要在每一个视图前面都添加修饰器,当初我就是这么作的,太累了。后来发现 django 中间件很是棒,能够进行全局控制,并且能够提升性能。提倡这种dry的哲学风格设计很是的有意思,django
先说下django 中间件的安装方法:浏览器
为了激活中间件组件,把它添加到你的settings模块的MIDDLEWARE_CLASSES列表中,在MIDDLEWARE_CLASSES里,每一个中间件组件经过一个字符串来表示:完整的到中间件的类名的Python路径,例如,这里是经过django-admin.py startproject建立的 session
默认的MIDDLEWARE_CLASSES:app
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', #'decorators.middleware.DecoratorsMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', )
Django安装部须要任何中间件--例如MIDDLEWARE_CLASSES能够为空,若是你想这样的话--可是强烈建议你使用CommonMiddleware 顺序是有意义的,在请求和视图阶段,Django使用MIDDLEWARE_CLASSES给定的顺序申请中间件,而在应答和异常阶段,Django使用相反的顺序申请中间件,即DjangoMIDDLEWARE_CLASSES看成一种视图方法的"包装器",在请求时,它自顶向下申请这个列表的中间件到视图,而在应答时它反序进行.函数
再说下django 中间件的定义方法:性能
* 请求预处理:process_request(self, request) :url
该方法在请求被接收和URL被解析来决定运行哪一个视图以前当即调用,它传递你可能想修改的HttpRequest对象 process_request()应该返回None或者HttpResponse对象,若是它返回None,Django将继续处理该请求,执行任何其它的中间件而后是合适的视图。若是请求中间件返回HttpResponse对象,Django将不会再调用其它任何中间件(任何类型)或者合适的视图,它将返回该应答。 spa
* 视图预处理:process_view(self, request, view, args, kwargs) :设计
该方法在请求中间件运行后和URL被解析到一个视图后和视图实际上被调用以前被调用,
参数说明:
* request HttpRequest对象
* view, Django将调用来执行该请求的视图函数,它是实际上的方法对象自己,而不是方法名字符串
* args 将被传递给视图的位置参数列表,不包括request参数(它一直是视图的第一个参数)
* kwargs 将被传递给视图的关键字参数字典
像process_request()同样,process_view()应该返回None或者HttpResponse对象,若是它返回None,Django将继续处理请求执行任何其它的视图中间件而后是合适的视图,若是视图中间件返回HttpResponse对象,Django将不会再调用其它任何中间件或者合适的视图,它将返回该应答
* 应答后处理:process_response(self, request, response)
该方法在视图方法已经调用和应答生成后调用,这是中间件修改应答输出的地方,输出压缩(见下)是应答中间件的一个显然的应用参数应该很是自明了--request是请求对象,response是从视图返回的应答对象不像请求和视图中间件,它们能够返回None,process_response()必须返回一个HttpResponse对象,该应答能够是传递给该
方法的原始应答(可能被修改了)或者新的应答
* 异常后处理:process_exception(self, request, exception)
该方法只在出错而且视图触发不可捕获的异常时调用,不包括Http404异常,你可使用这个钩子来发送错误通知,在一个日志文件记录信息,或者甚至尝试自动恢复该错误。该方法的参数是咱们一直处理的一样的request对象和视图方法触发的真正的Exception对象exception。process_exception()可能返回一个做为应答显示给浏览器的HttpResponse或者返回None来继续Django内建的异常处理。
好比咱们写了个例子
MIDDLEWARE_CLASSES = (
'apps.auth.middleware.DecoratorsMiddleware',
)
而后DecoratorsMiddleware定义的方法是:
#coding=utf-8 import urllib from django.template import RequestContext from django.shortcuts import render_to_response class DecoratorsMiddleware(object): """ 若是返回的对象是字典,就对它进行处理 """ def process_response(self, request, response): if type(response) == dict: param_dict = {} for k,v in request.GET.items(): if k == 'last_id': param_dict['last_id'] = response['ret'].get('last_id','') else: param_dict[k] = v.encode('utf-8') if not param_dict.get('last_id'): param_dict['last_id'] = response['ret'].get('last_id','') response['ret']['params'] = urllib.urlencode(param_dict) response['ret'] = dict(response['ret'], **param_dict) return render_to_response( response['template'], response['ret'], RequestContext(request, {}), ) return response
最后总结一下django 中间件不是很难,用一下就应该比较清楚了。