Django中间件实战:FBV/CBV日志全兼容

在 Django 开发中,中间件 是请求、响应流程的「全局拦截器」,FBV/CBV 是两种核心视图写法。本文带你从零实现自定义日志中间件,兼容函数视图和类视图,同时清晰对比两种视图的使用场景,轻松掌握非侵入式的请求增强能力!

一、实验核心目标

  1. 学会在 Django 中自定义中间件,掌握请求 / 响应全流程拦截

  2. 理清中间件执行顺序,实现请求日志、视图埋点、异常捕获

  3. 对比 FBV(函数视图)和 CBV(类视图)写法,理解适用场景

  4. 最终效果:访问任意接口,控制台自动打印请求路径、方法、视图名、响应状态码、异常信息

二、Django 中间件:全局请求「拦截器」

1. 核心概念

Django 中间件是介于浏览器请求视图函数 之间的钩子层,请求会先经过中间件,响应会再经过中间件返回浏览器,不修改业务代码就能实现全局功能增强。

2. 经典应用场景

  • 统一请求日志记录
  • 用户登录校验、IP 黑名单拦截
  • 全局异常处理
  • 响应头统一配置
  • 接口访问埋点统计

思想类比:和 SpringBoot 的拦截器、AOP 完全一致,都是非侵入式的功能扩展!

3. 完整执行流程

复制代码
浏览器发送请求
        ↓
process_request(请求进入视图前)
        ↓
process_view(视图执行前)
        ↓
执行 FBV/CBV 视图
        ↓
视图报错 → process_exception(异常捕获)
        ↓
process_response(响应返回前)
        ↓
浏览器接收响应

4. 核心方法说明

方法 执行时机 核心作用
process_request 请求刚进入 获取请求方法、路径,做基础校验
process_view 视图执行前 获取视图名称、参数,埋点日志
process_exception 视图报错时 捕获全局异常,打印错误信息
process_response 响应返回前 修改响应头、记录状态码

三、实战第一步:自定义日志中间件

1. 创建中间件文件

在你的 Django 应用目录下,新建 middleware.py 文件,编写兼容 FBV/CBV 的日志中间件:

运行

复制代码
# 你的应用名/middleware.py
from django.utils.deprecation import MiddlewareMixin

class SimpleLogMiddleware(MiddlewareMixin):
    """
    自定义日志中间件:
    1. 记录请求入口信息
    2. 打印即将执行的视图(兼容FBV/CBV)
    3. 捕获视图全局异常
    4. 记录响应状态码 + 自定义响应头
    """

    def process_request(self, request):
        """请求进入视图前执行"""
        print(f"\n[中间件] 请求进入:{request.method} {request.path_info}")

    def process_view(self, request, view_func, view_args, view_kwargs):
        """视图执行前执行,核心:兼容FBV和CBV获取真实视图名"""
        # 兼容CBV:获取类视图的类名
        view_class = getattr(view_func, "view_class", None)
        view_name = view_class.__name__ if view_class else view_func.__name__

        print(f"[中间件] 即将执行视图:{view_name}")
        print(f"[中间件] 视图参数:args={view_args}, kwargs={view_kwargs}")
        print(f"[中间件] 请求详情:path={request.path_info}, method={request.method}")

    def process_exception(self, request, exception):
        """视图执行报错时自动触发"""
        print(f"[中间件] 视图异常:{exception}")

    def process_response(self, request, response):
        """响应返回浏览器前执行"""
        print(f"[中间件] 响应返回:状态码={response.status_code}")
        # 自定义响应头,标记中间件已生效
        response["X-Request-Log"] = "enabled"
        return response

关键技巧process_view 中通过 view_class 兼容 CBV,避免类视图只显示 view 而无法识别真实类名!

2. 注册中间件(核心步骤)

打开项目 settings.py,在 MIDDLEWARE 列表末尾注册自定义中间件:

运行

复制代码
# settings.py
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',

    # 格式:应用名.middleware.中间件类名
    '你的应用名.middleware.SimpleLogMiddleware',
]

注意:中间件顺序决定执行优先级,请求从上到下执行,响应从下到上执行

四、实战第二步:编写 FBV + CBV 视图

我们同时实现两种视图,测试中间件的兼容性。

1. FBV 函数视图(Function Based View)

适合简单业务,代码直接易懂:

运行

复制代码
# 你的应用名/views.py
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt  # 忽略CSRF校验,方便测试
def login_fbv(request):
    """FBV登录视图:手动判断请求方法"""
    if request.method == "GET":
        return HttpResponse("GET 请求 - FBV 视图")

    if request.method == "POST":
        # 获取表单参数
        username = request.POST.get("user")
        password = request.POST.get("pwd")
        
        # 简单校验
        if username == "admin" and password == "123456":
            return HttpResponse("登录成功 - FBV 视图")
        return HttpResponse("登录失败 - FBV 视图")

    # 不支持的请求方法
    return HttpResponse("仅支持GET/POST", status=405)

2. CBV 类视图(Class Based View)

适合复杂业务,按请求方法拆分逻辑,结构清晰:

运行

复制代码
# 你的应用名/views.py
from django.http import HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt

class LoginCBV(View):
    """CBV登录视图:自动匹配GET/POST方法"""
    
    @csrf_exempt
    def dispatch(self, request, *args, **kwargs):
        # 重写dispatch,忽略CSRF校验
        return super().dispatch(request, *args, **kwargs)

    def get(self, request):
        """自动处理GET请求"""
        return HttpResponse("GET 请求 - CBV 视图")

    def post(self, request):
        """自动处理POST请求"""
        username = request.POST.get("user")
        password = request.POST.get("pwd")
        
        if username == "admin" and password == "123456":
            return HttpResponse("登录成功 - CBV 视图")
        return HttpResponse("登录失败 - CBV 视图")

五、实战第三步:配置路由

在应用的 urls.py 中配置两个测试接口,CBV 必须调用 as_view() 转换为 Django 可识别的函数:

运行

复制代码
# 你的应用名/urls.py
from django.urls import path
from . import views

urlpatterns = [
    # FBV 路由:直接写函数名
    path('login/fbv/', views.login_fbv, name='login_fbv'),
    # CBV 路由:必须调用 as_view()
    path('login/cbv/', views.LoginCBV.as_view(), name='login_cbv'),
]

六、运行项目 + 测试效果

1. 启动 Django 服务

运行

复制代码
# 检查项目配置
python manage.py check
# 启动服务
python manage.py runserver

2. 访问测试接口

浏览器访问:

  • FBV:http://127.0.0.1:8000/login/fbv/
  • CBV:http://127.0.0.1:8000/login/cbv/

3. 控制台输出效果(中间件生效!)

复制代码
[中间件] 请求进入:GET /login/fbv/
[中间件] 即将执行视图:login_fbv
[中间件] 视图参数:args=(), kwargs={}
[中间件] 请求详情:path=/login/fbv/, method=GET
[中间件] 响应返回:状态码=200

[中间件] 请求进入:GET /login/cbv/
[中间件] 即将执行视图:LoginCBV
[中间件] 视图参数:args=(), kwargs={}
[中间件] 请求详情:path=/login/cbv/, method=GET
[中间件] 响应返回:状态码=200

4. 异常捕获测试

在 FBV 视图中手动制造错误,测试异常拦截:

运行

复制代码
@csrf_exempt
def login_fbv(request):
    1 / 0  # 制造除零异常
    # ... 原有代码

刷新接口,控制台自动打印异常:

复制代码
[中间件] 视图异常:division by zero

测试完成后删除错误代码即可!

七、FBV vs CBV 终极对比

对比维度 FBV 函数视图 CBV 类视图
全称 Function Based View Class Based View
编写方式 普通函数 继承 View 的类
请求处理 手动判断 request.method 自动匹配 get()/post()
代码结构 简洁直接,代码集中 结构清晰,按方法拆分
扩展性 弱,复杂业务易臃肿 强,支持继承 / 重写
路由写法 views.login_fbv views.LoginCBV.as_view()
适用场景 简单接口、小功能页面 复杂业务、需要复用逻辑

开发建议:小功能用 FBV 快速开发,复杂业务用 CBV 规范代码!

八、实验总结

1. 中间件核心价值:非侵入式实现全局功能,无需修改每个视图就能统一记录日志、捕获异常。

2. 执行顺序process_requestprocess_view → 视图 → process_exception(异常)→ process_response

3. 兼容技巧process_view 中通过view_class兼容 CBV 视图,精准获取视图名称。

4. 视图选择:简单业务 FBV 首选,复杂业务 CBV 更优。

这套中间件 + 视图的组合,是Django开发中全局日志、权限校验、异常处理的标准方案,直接复用就能提升项目开发效率!

【附件】

相关所有代码可点击下方链接见详情:

django-middleware-fbv-cbv-demo: Django 自定义中间件实战,实现请求日志、异常捕获,同时对比 FBV 函数视图与 CBV 类视图的写法与执行流程。https://gitee.com/Zhang-Siyu0066/django-middleware-fbv-cbv-demo

相关推荐
ㄟ留恋さ寂寞1 小时前
如何授权AWR报告生成_GRANT SELECT ANY DICTIONARY诊断权限
jvm·数据库·python
_376271531 小时前
mysql如何实现定时清理缓存数据_利用event scheduler执行
jvm·数据库·python
m0_748554811 小时前
SQL如何实现多层级分组统计_使用GROUP BY多字段组合
jvm·数据库·python
夕除1 小时前
spring boot--08
开发语言·windows·python
kay...1 小时前
FreeSurfer 核磁共振重建
python·eeg
TDengine (老段)1 小时前
TDengine 集群拓扑深度解析 — 节点发现、EP 机制与负载均衡
大数据·数据库·人工智能·重构·负载均衡·时序数据库·tdengine
Kiyra1 小时前
异步任务不用 Kafka 也行:用 Redis Stream 搭一套轻量级 Producer/Consumer 框架
数据库·人工智能·redis·分布式·后端·缓存·kafka
进阶的猿猴1 小时前
Rsa简单实现接口到期限制(springBoot)
java·spring boot·后端
Java编程爱好者1 小时前
MySQL / PostgreSQL DDL 审核自动化:从人工 review 到 CI 拦截
后端