
在 django 5.0+ 中,`decorator_from_middleware` 要求中间件类必须继承 `middlewaremixin`,否则会因协议不兼容而失效;本文详解如何正确编写可装饰化的中间件,并安全应用于 drf 视图。
Django 自 1.10 起统一了中间件接口,推荐使用基于类的“新式中间件”(即实现 __call__ 方法),但decorator_from_middleware 并不直接支持裸 __call__ 中间件——它底层依赖旧式中间件的 process_request/process_response 钩子机制。因此,即使你使用的是 Django 5.0,若需通过 decorator_from_middleware 将中间件转为装饰器,必须显式继承 django.utils.deprecation.MiddlewareMixin。
MiddlewareMixin 是一个适配器类,它自动将 __call__ 方法桥接到标准中间件生命周期钩子(如 process_request、process_view、process_response 等)。没有它,decorator_from_middleware 无法识别和包装你的中间件逻辑。
✅ 正确写法如下:
# users/middleware.py
from django.utils.deprecation import MiddlewareMixin
class SimpleMiddleware(MiddlewareMixin):
def process_request(self, request):
print("inside the custom middleware — before view execution")
# ✅ 此处添加 Token 解析、角色校验等前置逻辑
# 例如:validate_token_and_roles(request)
def process_response(self, request, response):
# 可选:响应后处理(如日志、头信息注入)
return response⚠️ 注意:
- 不再需要手动定义 __init__ 和 __call__;
- process_request 返回 None 表示继续流程;若返回 HttpResponse,则短路后续中间件与视图(常用于鉴权拦截);
- 若需访问视图函数信息,可使用 process_view(self, request, view_func, view_args, view_kwargs)。
接着,在视图中按需装饰:
# views.py
from django.utils.decorators import decorator_from_middleware
from users.middleware import SimpleMiddleware
simple_decorator = decorator_from_middleware(SimpleMiddleware)
class UserPoolInfo(APIView):
@simple_decorator
def get(self, request):
user_manager_object = UserManager()
user_pool_info = user_manager_object.get_user_pool_info()
response_data = {
"status": "Success",
"statusCode": status.HTTP_200_OK,
"message": "fetched user pool information",
"data": user_pool_info
}
return Response(response_data, status.HTTP_200_OK)? 关键提醒:
- 无需将该中间件加入全局 MIDDLEWARE 设置——decorator_from_middleware 生成的装饰器是独立运行的,全局注册反而会导致重复执行;
- 若你同时需要「全局应用」和「按视图装饰」两种模式,建议拆分为两个中间件类,或统一用 @method_decorator + MiddlewareMixin 组合(更推荐);
- 对于 DRF 的 APIView,确保装饰器作用于具体 HTTP 方法(如 @simple_decorator 放在 def get() 上),而非类级别(@simple_decorator 放在类上无效)。
? 进阶建议:对于 Token 鉴权场景,更符合 DRF 生态的做法是自定义 Authentication 类(继承 BaseAuthentication)并配合 permission_classes,这样既能复用 DRF 的认证流程,又支持细粒度控制(如 per-view 或 per-method 启用)。但若需在视图执行前后插入非认证类逻辑(如审计日志、上下文注入),本方案仍是简洁可靠的选择。
总结:decorator_from_middleware 不是“任意中间件都能转”,而是专为 MiddlewareMixin 子类设计的桥梁工具。坚持继承 MiddlewareMixin、使用 process_* 钩子、避免手动 __call__,即可稳定实现按需装饰。








