中间件定义:
中间件是一个、一个的管道,如果相对任何所有的通过Django的请求进行管理都需要自定义中间件
中间件可以对进来的请求和出去的请求进行控制
中间件是一类。
看下面的代码在settings里中间件的类:
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', ]
当有请求过来的时候,默认从上倒下执行!然后在返回的时候从下面在返回回去,如下图:
2、自定义中间件
中间件中可以定义四个方法,分别是:
- process_request(self,request)
- process_view(self, request, callback, callback_args, callback_kwargs)
- process_exception(self, request, exception)
- process_response(self, request, response)
process_exception 这个方法只有在出现错误的时候才会触发
先写一个自定义中间件,然后在看他的原理和源码:
2.1、自定义中间件
class Testmiddle(object): def process_request(self,request): print 'Testmiddle process_request' def process_view(self, request, callback, callback_args, callback_kwargs): print 'Testmiddle process_view' def process_exception(self, request, exception): pass def process_response(self, request, response): print 'Testmiddle process_response' return response class Nextmiddle(object): def process_request(self,request): print 'Nextmiddle process_request' def process_view(self, request, callback, callback_args, callback_kwargs): print 'Nextmiddle process_view' def process_exception(self, request, exception): pass def process_response(self, request, response): print 'Nextmiddle process_response' return response
2.2、注册中间件
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.middle.Testmiddle', 'middleware.middle.Nextmiddle', ]
2.3、测试使用url和views
from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/$', views.index), ]
def index(request): print 'This app01 Views.index' return HttpResponse('OK')
2.4、查看输出结果:
''' Testmiddle process_request Nextmiddle process_request Testmiddle process_view Nextmiddle process_view This app01 Views.index Nextmiddle process_response Testmiddle process_response '''
从输出结果可以看出:
他是先执行Testmiddle 的request 方法又执行了Nextmiddle的 process_request方法。。。。
2.5、原理:
当请求进来了到达中间件
去settings里面找到MIDDLEWARE_CLASSES,MIDDLEWARE_CLASSES是一个元组
有4个列表:
process_request_lsit = [] process_view_list = [] process_response_list = [] 然后他循环MIDDLEWARE_CLASSES这个类: for 类 in MIDDLEWARE_CLASSES: obj = 类() if obj里有process_request方法: process_request_lsit.append(obj.process_request)
然后循环后后执行:
for i in process_request_list: i() #加括号执行方法 for i in process_view_list: i() ............
3、中间件的流程梳理
首先看下自定义的中间件中的process_response方法他是有返回值的其他的是没有返回值的。这个return response是什么呢?
这个response就是咱们自定义的views.index返回的结果!
def process_response(self, request, response): print 'Testmiddle process_response' return response
如果在其他的没有返回值得,仅有process_response有返回值得话他的请求流程是这样的:
但是如果在process_request或者process_view又返回值得话那么流程就完全不一样了!
举例:如果有m1和m2两个中间件,如果我在m1中的request方法中设置了,如果访问为1.1.1.1那么返回要一个404,那么他的访问流程是这样的:
process_exception 什么时候触发呢?咱们定义的views.index出错的时候他就会捕捉到然后执行咱们定义的process_exception方法如下图:
Django缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者Redis中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。
举个例子来说:如果访问量比较大的时候,有很多相同的操作比如:有时候请求的数据比如访问同一条数据,或者同一个页面的时候,其实是没必要的。
Django支持,mysql,Redis、Memecache、文件的方式做缓存,并且可以设置超时时间。
settings配置:
CACHES = { 'default': { #定义已文件的方式进行cache 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #cache文件的存放路径 'LOCATION': os.path.join(BASE_DIR, 'cache'), #超时时间为600妙 'TIMEOUT': 600, 'OPTIONS': { 'MAX_ENTRIES': 1000 } } }
给请求应用,就是使用装饰器
from django.views.decorators.cache import cache_page #这里设置的是 60秒 * 15 ,15分钟之后 @cache_page(60 * 15) def cache_page(request): current = str(time.time()) return HttpResponse(current)