Django 中间件

文章目录


一、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.中间件四个方法

  1. 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}')
  1. 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__}')
  1. 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)
  1. 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 参数都是同一个请求对象

相关推荐
MessiGo23 分钟前
Python 爬虫 (1)基础 | 基础操作
开发语言·python
Tech Synapse29 分钟前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
.生产的驴29 分钟前
SpringCloud OpenFeign用户转发在请求头中添加用户信息 微服务内部调用
spring boot·后端·spring·spring cloud·微服务·架构
微信-since811921 小时前
[ruby on rails] 安装docker
后端·docker·ruby on rails
肥猪猪爸1 小时前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
LZXCyrus1 小时前
【杂记】vLLM如何指定GPU单卡/多卡离线推理
人工智能·经验分享·python·深度学习·语言模型·llm·vllm
Enougme1 小时前
Appium常用的使用方法(一)
python·appium
懷淰メ1 小时前
PyQt飞机大战游戏(附下载地址)
开发语言·python·qt·游戏·pyqt·游戏开发·pyqt5
hummhumm2 小时前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
hummhumm2 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架