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 参数都是同一个请求对象

相关推荐
一只爱打拳的程序猿2 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
yannan2019031310 分钟前
【算法】(Python)动态规划
python·算法·动态规划
竹笋常青17 分钟前
《流星落凡尘》
django·numpy
蒙娜丽宁20 分钟前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
光芒再现dev22 分钟前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
好喜欢吃红柚子35 分钟前
万字长文解读空间、通道注意力机制机制和超详细代码逐行分析(SE,CBAM,SGE,CA,ECA,TA)
人工智能·pytorch·python·计算机视觉·cnn
小馒头学python40 分钟前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
zmd-zk1 小时前
kafka+zookeeper的搭建
大数据·分布式·zookeeper·中间件·kafka
神奇夜光杯1 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
千天夜1 小时前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流