如何在Django的pre_delete信号中访问request.user?
在Django的pre_delete信号中访问request.user的方案
在Django的pre_delete信号里默认是拿不到request.user的,因为信号本身脱离请求上下文。下面是两个适配现代Django版本(3.2+)的可行方案:
方案一:使用线程局部存储(通用场景)
这个方案能让所有请求触发的信号都拿到当前用户,包括admin后台的删除操作。
- 创建线程局部存储工具
新建utils/thread_locals.py文件:
import threading _thread_locals = threading.local() def set_current_request(request): _thread_locals.request = request def get_current_request(): return getattr(_thread_locals, 'request', None)
- 添加请求中间件
新建middleware.py文件:
from django.utils.deprecation import MiddlewareMixin from .utils.thread_locals import set_current_request class RequestMiddleware(MiddlewareMixin): def process_request(self, request): set_current_request(request)
然后在项目settings.py的MIDDLEWARE列表里添加这个中间件(建议放在靠前位置):
MIDDLEWARE = [ 'your_app.middleware.RequestMiddleware', # ... 其他中间件 ]
- 在信号处理中获取用户
from django.db.models.signals import pre_delete from django.dispatch import receiver from .models import YourModel from .utils.thread_locals import get_current_request @receiver(pre_delete, sender=YourModel) def handle_pre_delete(sender, instance, **kwargs): request = get_current_request() if request and hasattr(request, 'user'): current_user = request.user # 这里可以用current_user执行你需要的逻辑,比如记录操作日志
注意:如果你的项目使用了异步视图,线程局部存储会失效,此时需要改用
contextvars模块来存储请求上下文。
方案二:手动传递用户参数(特定删除场景)
如果只有特定视图会触发删除操作,直接在删除时给信号传递user参数更简单,不需要中间件。
- 视图中手动发送信号并传递用户
from django.shortcuts import get_object_or_404, redirect from django.db.models.signals import pre_delete from .models import YourModel def delete_object(request, pk): obj = get_object_or_404(YourModel, pk=pk) # 删除前手动发送pre_delete信号并带上user参数 pre_delete.send(sender=YourModel, instance=obj, user=request.user) obj.delete() return redirect('object_list')
- 信号处理函数接收用户参数
from django.db.models.signals import pre_delete from django.dispatch import receiver from .models import YourModel @receiver(pre_delete, sender=YourModel) def handle_pre_delete(sender, instance, user=None, **kwargs): if user: # 直接使用传入的user对象进行操作 print(f"用户 {user.username} 即将删除对象 {instance}")
这个方案的缺点是:所有删除对象的地方都需要手动传递user参数,否则信号里拿不到用户信息。
内容的提问来源于stack exchange,提问作者user15364819
相关产品推荐
相关产品推荐

