django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
MIDDLEWARE_CLASSES = [
# 'ZHONGJIANJIAN.text.text1Middleware', #自定义中间件
'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',
]
中间件中可以定义四个方法,分别是:
process_request(self,request) process_view(self, request, callback, callback_args, callback_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response)
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户
djanjo 中间件版本差异报错处理:
1.9.x版本以下djanjo中间件定义规则
class CommonMiddleware(object):
def process_request(self, request):
return None
def process_response(self, request, response):
return response
最新的1.10.x版本djanjo中间件定义规则----------不是执行的类下的方法,而是执行MiddlewareMixin对象的__call__方法(方法中调用,process_request等方法)
from djanjo.utils.deprecation import MiddlewareMixin
class CommonMiddleware(MiddlewareMixin):
def process_request(self, request):
return None
def process_response(self, request, response):
return response
下面的方法就可以让 中间件 兼容 Django新版本和旧版本------------上面俩种的合并
__call__ 方法会先调用 self.process_request(request),接着执行 self.get_response(request) 然后调用 self.process_response(request, response)
try:
from django.utils.deprecation import MiddlewareMixin # Django 1.10.x
except ImportError:
MiddlewareMixin = object # Django 1.4.x - Django 1.9.x
class SimpleMiddleware(MiddlewareMixin):
def process_request(self, request):
pass
def process_response(request, response):
pass
新版本中 django.utils.deprecation.MiddlewareMixin 的 源代码 如下:
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
功效:
比如我们要做一个 拦截器,比如统计一分钟访问页面数,太多就把他的 IP 加入到黑名单 BLOCKED_IPS,发现有恶意访问网站的人,就拦截他!
class BlockedIpMiddleware(object):
def process_request(self, request):
if request.META['REMOTE_ADDR'] in getattr(settings, "BLOCKED_IPS", []):
return http.HttpResponseForbidden('<h1>Forbidden</h1>')
中间件生命周期(1.9.x版本以下):
1>正常情况(有俩个中间件的情况)
process_request1---->process_request2---->process_view1------process_view2----->url---->views---> process_response2----->process_response1
2>在任意一个process_request中只要有return直接跳到process_response
process_request1---->process_request2----> process_response2----->process_response1
3>如果返回值中有render的话走process_template_response
process_request1---->process_request2---->process_view1------process_view2----->url---->views--->process_template_response2---->
process_template_response1--->process_response2----->process_response1
4>views中出现错误的时候走process_exceptionprocess_response
process_request1---->process_request2---->process_view1--->process_view2----->url---->views---> process_exceptionprocess_response2--->
process_exceptionprocess_response1
中间件生命周期(1.10.x版本及以上):
和1.9.x版本以下相比,不同点在于,当request中出现return的时候,直接到最外层的response,而不经过里层的response
自定义中间件
1、创建中间件类
class RequestExeute(object):
def process_request(self,request):
pass
def process_view(self, request, callback, callback_args, callback_kwargs):
i =1
pass
def process_exception(self, request, exception):
pass
def process_response(self, request, response):
return response
2、注册中间件
MIDDLEWARE_CLASSES = (
'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',
'wupeiqi.middleware.auth.RequestExeute',
)
缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回
Django中提供了6种缓存方式:
- 开发调试
- 内存
- 文件
- 数据库
- Memcache缓存(python-memcached模块)
- Memcache缓存(pylibmc模块)
1、配置
a、开发调试
# 此为开始调试用,实际内部不做任何操作 # 配置: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎 'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存个数(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, 'KEY_PREFIX': '', # 缓存key的前缀(默认空) 'VERSION': 1, # 缓存key的版本(默认1) 'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】) } } # 自定义key def default_key_func(key, key_prefix, version): """ Default function to generate keys. Constructs the key used by all other methods. By default it prepends the `key_prefix'. KEY_FUNCTION can be used to specify an alternate function with custom key making behavior. """ return '%s:%s:%s' % (key_prefix, version, key) def get_key_func(key_func): """ Function to decide which key function to use. Defaults to ``default_key_func``. """ if key_func is not None: if callable(key_func): return key_func else: return import_string(key_func) return default_key_func