1.中间件
中间件可以介入Django的请求和响应处理过程,修改Django的输入或输出,简单来说,中间件就是在每次执行之前都会被拦截处理,之后再继续执行本来的业务
使用场景: 当某些操作在每次请求或响应时都会执行时,可以写在中间件中
特点: 面向切面编程、无侵害式编程,不用直接修改框架源码,就可以达到自己想要的执行结果
我们可以在Django项目的settings.py配置文件中找到有关中间件的设置列表MIDDLEWARE
2.中间件的常用方法
Django的中间件会执行6个方法
# 初始化时调用
def __init__(self, get_response=None):
pass
# 处理收到的请求前调用
def process_request(self, request):
pass
# 处理视图函数前调用
def process_view(self, request, view_func, view_args, view_kwargs):
pass
# 处理模板前调用
def process_template_response(self, request, response):
pass
# 返回相应数据之前调用
def process_response(self, request, response):
pass
# 当发生异常时调用
def process_exception(self, request,exception):
pass
3.执行顺序
我们可以写一个自定义的中间件,但是必须要继承Django的中间件类MiddlewareMixin,自定义的类可以实现上面的一个或多个方法
middleware.py
from django.utils.deprecation import MiddlewareMixin
class TestMiddleware1(MiddlewareMixin):
def __init__(self, get_response=None):
super().__init__()
self.get_response = get_response
print('初始化,test1')
def process_request(self, request):
print('处理请求前,test1')
def process_view(self, request, view_func, view_args, view_kwargs):
print('处理视图前,test1')
def process_response(self, request, response):
print('响应前,test1')
return response
class TestMiddleware2(MiddlewareMixin):
def __init__(self, get_response=None):
super().__init__()
self.get_response = get_response
print('初始化,test2')
def process_request(self, request):
print('处理请求前,test2')
def process_view(self, request, view_func, view_args, view_kwargs):
print('处理视图前,test2')
def process_response(self, request, response):
print('响应前,test2')
return response
settings.py
# 注册自定义的中间件
MIDDLEWARE = [
...
# 使用路径:应用名.包名.文件名.类名
'middleware.TestMiddleware1',
'middleware.TestMiddleware2',
]
运行程序,我们可以看到中间件的执行顺序
4.使用中间件验证是否登录
定义中间件,middlewares.py
class LoginRequireMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
super().__init__()
self.get_response = get_response
self.white_list = ["/login/", "/register/"] # 白名单
self.black_list = [] # 黑名单
def process_request(self, request):
path = request.path
if request.user.is_authenticated or path in self.white_list:
return None
elif path in self.black_list:
return JsonResponse({"code": 0, "error": "禁止访问"}, status=403)
else:
return HttpResponseRedirect(reverse('login'))
在设置中启用
MIDDLEWARE = [
...
"XXX.XXX.middlewares.LoginRequireMiddleware",
...
]
5.使用中间件记录访问日志
middlewares.py
class OperateMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
super().__init__()
self.get_response = get_response
def process_request(self, request):
...
def process_response(self, request, response):
current_user = request.user
if current_user.id:
info_dict = {
"user_id": current_user.id,
"user_name": current_user.username,
"method": request.method,
"path": request.path,
"params": dict(request.GET.lists()) if request.GET else dict(request.POST.lists()),
"res": response.content.decode() if isinstance(response, JsonResponse) else None,
"create_time": get_datetime_now_str()
}
# 自己封装一个wrapper
redis_ = RedisWrapper(get_redis_connection("default"), "ops_journal")
redis_.rpush(json.dumps(info_dict))
return response