Django中间件
2016-03-15 17:39
459 查看
中间件
一、url请求经过中间件的执行顺序
中间件描述起来可能会很麻烦,一张图片更能简洁明了的django中间件的大概作用。![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315173854037-2081342551.jpg)
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。
![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315201812678-1856262640.jpg)
每一个中间件中都可以定义四个方法,分别是:
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_exception(self, request, exception)
process_response(self, request, response)
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315201916115-278107915.png)
二、自定义中间件
1、创建放置中间件的目录和文件![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315204248615-1874882242.jpg)
2、自定义中间件
class mmm(object): def process_request(self, request): print 'mmm.process_request' def process_view(self, request, callback, callback_args, callback_kwargs): print 'mmm.process_view' def process_response(self, request, response): print 'mmm.process_response' return response class xxx(object): def process_request(self, request): print 'xxx.process_request' def process_view(self, request, callback, callback_args, callback_kwargs): print 'xxx.process_view' def process_response(self, request, response): print 'xxx.process_response' return response
3、在settings.py里注册自定义的中间件类
MIDDLEWARE_CLASSES = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'middleware.middle1.mmm', 'middleware.middle1.xxx', ]
在执行时,可以看到请求在经过这中间件时的执行顺序
![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315205105287-1715822774.jpg)
只有当程序执行错误时,才会执行process_exception(self, request, exception)
可以在views里的函数里触发一个错误,然后执行程序。
![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315213250474-1168107719.jpg)
三、django中间件源码剖析
中间件的源码可以再wsgi.py里找到![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315215333537-1330983825.jpg)
点击进入到WSGIHandler类:
![](https://images2015.cnblogs.com/blog/773921/201603/773921-20160315215450053-520710107.jpg)
在WSGIHandler类的里面的 _call_方法里面会执行self.load_middleware()
在load_middleware方法里,定义了5个空列表。此方法会去循环settings.py下的MIDDLEWARE_CLASSES列表中所有中间件的类名。然后,在通过hasattr反射的方法去查找所有的中间件类里面是否有对应的process_request,process_view,process_response,process_exception,如果有这些方法就会把他们分别一一添加到定义的五个空列表里,然后再去循环四个列表,并分别去执行列表下的函数
def load_middleware(self): """ Populate middleware lists from settings.MIDDLEWARE_CLASSES. Must be called after the environment is fixed (see __call__ in subclasses). """ self._view_middleware = [] self._template_response_middleware = [] self._response_middleware = [] self._exception_middleware = [] request_middleware = [] for middleware_path in settings.MIDDLEWARE_CLASSES: mw_class = import_string(middleware_path) try: mw_instance = mw_class() except MiddlewareNotUsed as exc: if settings.DEBUG: if six.text_type(exc): logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) else: logger.debug('MiddlewareNotUsed: %r', middleware_path) continue if hasattr(mw_instance, 'process_request'): request_middleware.append(mw_instance.process_request) if hasattr(mw_instance, 'process_view'): self._view_middleware.append(mw_instance.process_view) if hasattr(mw_instance, 'process_template_response'): self._template_response_middleware.insert(0, mw_instance.process_template_response) if hasattr(mw_instance, 'process_response'): self._response_middleware.insert(0, mw_instance.process_response) if hasattr(mw_instance, 'process_exception'): self._exception_middleware.insert(0, mw_instance.process_exception) # We only assign to this when initialization is complete as it is used # as a flag for initialization being complete. self._request_middleware = request_middleware
相关文章推荐
- Django URL 分发
- AlphaGo最终局战胜李世石
- AlphaGo最终局战胜李世石
- Windows下面替换命令实现,最新修复一个BUG
- mongo集群分片如何添加认证密码
- 去掉Googl默认界面的logo下面的尴尬的文字,对面的菇凉请看过来!!!
- django filter 中使用 or (django中Q)
- 当View为GONE状态时获取View的宽高
- CodeForces#5A. Chat Server's Outgoing Traffic
- AlphaGo:黑色方碑?
- lightoj 1030 Discovering Gold 概率dp求期望
- mongo 删除内嵌数组元素
- Go语言核心之美 1.3-赋值及类型声明篇
- Django路由系统
- 科普:alphago是什么
- 【Google Earth】使用GPS数据gpx创建航迹
- [Canvas绘图] 第34节 藏图阁(14) AlphaGo与李世石的围棋大战之第四局
- 基于go-ceph创建CEPH块设备及快照
- Go语言以匿名组合的方式实现继承
- sougou word library TXT download