中间件类
from django.http import HttpResponse, Http404
from django.utils.deprecation import MiddlewareMixin
class MyMiddleWare(MiddlewareMixin):
def process_request(self, request):
'''
位置:进入主路由urls.py前被调用
功能:通常在这一层进行大面积的请求攻击过滤
返回值:返回None:程序继续向下执行
返回HttpResponse:请求结束,返回具体的HttpResponse给浏览器
'''
print("中间件方法 process_request 被调
用")
def process_view(self, request, callback,callback_args, callback_kwargs):
'''
位置:urls.py之后,在进入视图层自之前
功能:修改(regexp)匹配出来的url参数
参数:callback:即将调用的示图函数
callback_args和callback_kwargs:修改传进示图函数的参数
返回值:None:程序接着向下走
HttpResponse:请求结束,直接终止返回给浏览器
'''
print("中间件方法 process_view 被调用")
def process_response(self, request,response):
'''
位置:给到浏览器之前,做最后一层过滤
功能:e.g.博客型网站可在这儿过滤掉不雅词汇,能对比请求进来的时候和响应出去时候的变量
返回值:HttpResponse对象
'''
print("中间件方法 process_response 被调用")
return response
练习1:演示多个中间件的执行顺序
- 主项目下有个应用index,index的视图函数中
def mymiddle(request):
print('----------views start----------')
return HttpResponse('----------test is ok ------------')
- 在主项目目录下新建放中间件的文件夹middleware,在该文件夹下创建__init__.py文件和mymiddleware.py文件
- 中间件文件:mymiddleware.py中
from django.utils.deprecation import MiddlewareMixin
#第一个中间件
class MyMw(MiddlewareMixin):
def process_request(self, request):
print('MyMw process_request do ------')
def process_view(self, request, callback,callback_args, callback_kwargs):
print('MyMw process_view do ------')
def process_response(self, request,response): #response就是试图函数的response
print('MyMw process_response do -------')
return response
#第二个中间件
class MyMw2(MiddlewareMixin):
def process_request(self, request):
print('MyMw2 process_request do ------')
def process_view(self, request, callback,callback_args, callback_kwargs):
print('MyMw2 process_view do ------')
def process_response(self, request,response): #response就是试图函数的response
print('MyMw2 process_response do -------')
return response
- settings.py中添加中间件
MIDDLEWARE = [
'middleware.mymiddle.MyMw' #文件夹名.文件名.中间件类名
'middleware.mymiddle.MyMw2' #文件夹名.文件名.中间件类名
]
- 分布式路由中
from django.conf.urls import url
from . import views
urlpatterns = [
#http://127.0.0.1:8000/index/mymiddle
url(r'^mymiddle$',views.mymiddle)
]
- 在浏览器中访问127.0.0.1:8000/index/mymiddle
在终端中会打印出
MyMw process_request do ------ #进入主路由urls.py之前
MyMw2 process_request do ------
MyMw process_view do ------ #进入视图层之前
MyMw2 process_view do ------
----------views start---------- #在视图层中
MyMw process_response do ------- #出去了
MyMw2 process_response do -------
规律:进去的时候中间件按照顺序执行,出来的时候中间件倒过来执行
练习2:实现强制某个IP只能向url:/test 发送5次GET请求
from django.http import HttpResponse, Http404
from django.utils.deprecation import MiddlewareMixin
import re
class VisitLimit(MiddlewareMixin):
visit_times = {} #类属性{ip1:times,ip2:times,ip3:times}
def process_request(self,request):
#获取访问用户的IP地址
ip_address = request.META['REMOTE_ADDR']
#判断用户是否访问的/test路由,如果不是直接退出中间件
if not re.match('^/test',request.path_info): #request.path_info获取用户GET请求的路由
return
times = self.visit_times.get(ip_address,0) #0为如果没有该key时默认的返回值
print('IP:',ip_address,'已经访问过',times,'次!:',request.path_info)
#在类属性中计数
VisitLimiit.visit_times[ip_address] = times + 1
if times < 5:
return
return HttpResponse('你已经访问过' + str(times) + '次,您被禁止了')