文章目录
一、Django中间件介绍
中间件是一种强大的机制,用于实现各种功能,比如身份验证、日志记录、压缩、内容过滤等
Django 中间件是一个可以处理请求和响应的钩子框架。它们可以在 Django 处理请求的不同阶段执行代码,从而对请求和响应进行处理或修改,可以理解为是介于 HttpRequest 与 HttpResponse 处理之间的一道处理过程
在请求到达视图之前,Django 会按顺序调用中间件的 process_request 方法
在响应返回给客户端之前,Django 会按相反的顺序调用中间件的 process_response 方法
二、中间件的主要方法
1.Django默认中间件
bash
# 当 Django 启动时调用,通常用于初始化中间件
__init__(self, get_response):
# 在视图函数被调用之前执行,接收 request 对象,可以返回 None 或 HttpResponse 对象
process_request(self, request):
# 在视图函数执行之前被调用,接收视图函数的信息,可以返回 None 或 HttpResponse
process_view(self, request, view_func, view_args, view_kwargs):
# 在视图处理完请求后执行,接收 response 对象,可以返回修改后的 HttpResponse
process_response(self, request, response):
#当视图抛出异常时调用,可以返回 HttpResponse
process_exception(self, request, exception):
中间件组件配置在 settings.py
文件的 MIDDLEWARE 选项列表中
Django 默认的中间件配置:
bash
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
2.自定义中间件
下面是一个简单的自定义中间件示例,用于记录请求的 URL 和响应状态码
在fa目录下新增一个middleware.py
:
bash
import logging
class RequestLogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.logger = logging.getLogger(__name__)
def __call__(self, request):
# 处理请求前的日志记录
self.logger.info(f'Income request: {request.path}')
# 处理请求
response = self.get_response(request)
# 处理请求后的日志记录
self.logger.info(f'Response status: {response.status_code}')
return response
在settings.py
中增加中间件配置
bash
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 添加中间件
'fa.middleware.RequestLogMiddleware',
]
Django 的日志记录可以通过配置来输出到不同的目标,比如控制台或文件
默认情况下,Django 不会自动记录到文件,但你可以通过配置来实现
所以我们在settings.py
里面增加LOGGING
配置
bash
# 日志配置
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': os.path.join(BASE_DIR, 'django.log'), # 日志文件路径
'formatter': 'verbose',
},
},
'loggers': {
'fa.middleware': { # 使用你的实际中间件模块路径
'handlers': ['file'],
'level': 'DEBUG', # 确保级别足够低以捕获信息
'propagate': True,
},
'django': { # 确保 Django 的日志配置正常
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
这个时候我们再去请求一下项目的任意路由可以看到fa同级目录下会有一个django.log
3.中间件四个方法
process_request(self, request)
作用:在 Django 处理请求之前调用,可以在这里对请求进行修改或检查
返回值:可以返回 None(表示继续处理请求)或返回一个 HttpResponse 对象(表示请求处理终止,直接返回该响应)
bash
# 参数解释
# self:
# 类型:中间件类的实例
# 作用:代表当前中间件的实例,允许访问类的属性和其他方法
# request:
# 类型:django.http.HttpRequest 对象
# 作用:包含当前 HTTP 请求的所有信息,如请求方法、路径、GET/POST 数据、用户信息等
def process_request(self, request):
# 记录请求路径
self.logger.info(f'Incoming request: {request.path}')
process_view(self, request, view_func, view_args, view_kwargs)
作用:在请求的视图函数被调用之前调用,可以访问视图函数及其参数
返回值:可以返回 None(表示继续处理)或返回一个 HttpResponse 对象(终止请求处理并返回该响应)
bash
# 参数解释
# self:
# 类型:中间件类的实例
# 作用:代表当前中间件的实例,允许访问类的属性和其他方法
# request:
# 类型:django.http.HttpRequest 对象
# 作用:当前的 HTTP 请求对象
# view_func:
# 类型:视图函数
# 作用:即将被调用的视图函数(或类视图的 as_view 方法)
# view_args:
# 类型:列表(list)
# 作用:传递给视图函数的位置参数
# view_kwargs:
# 类型:字典(dict)
# 作用:传递给视图函数的关键字参数
def process_view(self, request, view_func, view_args, view_kwargs):
# 记录即将调用的视图函数
self.logger.info(f'About to call view: {view_func.__name__}')
process_exception(self, request, exception)
作用:当视图函数引发异常时调用。你可以在这里处理异常,例如记录日志或返回自定义错误响应
返回值:可以返回 None(表示不处理该异常),或者返回一个 HttpResponse 对象(表示处理了该异常并返回了响应)
bash
# 参数解释
# self:
# 类型:中间件类的实例
# 作用:代表当前中间件的实例,允许访问类的属性和其他方法
# request:
# 类型:django.http.HttpRequest 对象
# 作用:当前的 HTTP 请求对象
# exception:
# 类型:异常对象(Exception 的实例)
# 作用:视图函数中抛出的异常
def process_exception(self, request, exception):
# 记录异常
self.logger.error(f'Exception occurred: {exception}')
# 返回一个自定义错误响应
return HttpResponse('An error occurred', status=500)
process_response(self, request, response)
作用:在视图函数处理完请求后调用,可以在这里对响应进行修改
返回值:必须返回一个 HttpResponse 对象
bash
# 参数解释
# self:
# 类型:中间件类的实例
# 作用:代表当前中间件的实例,允许访问类的属性和其他方法
# request:
# 类型:django.http.HttpRequest 对象
# 作用:当前的 HTTP 请求对象
# response:
# 类型:django.http.HttpResponse 对象
# 作用:即将返回给客户端的 HTTP 响应对象
def process_response(self, request, response):
# 记录响应状态
self.logger.info(f'Response status: {response.status_code}')
return response
工作流程:
bash
1.请求进入中间件:
process_request 先执行
如果返回 HttpResponse,后续处理会被终止
2.视图函数调用:
process_view 被调用,视图函数执行前可以进行进一步处理
3.视图函数处理:
如果视图函数抛出异常,process_exception 将被调用
4.响应返回:
视图函数返回响应后,process_response 被调用。
当配置多个中间件时,会按照 MIDDLEWARE中 的注册顺序,也就是列表的索引值,顺序执行,不同中间件之间传递的 request 参数都是同一个请求对象