You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django的pre_delete信号中访问request.user?

在Django的pre_delete信号中访问request.user的方案

在Django的pre_delete信号里默认是拿不到request.user的,因为信号本身脱离请求上下文。下面是两个适配现代Django版本(3.2+)的可行方案:

方案一:使用线程局部存储(通用场景)

这个方案能让所有请求触发的信号都拿到当前用户,包括admin后台的删除操作。

  1. 创建线程局部存储工具
    新建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)
  1. 添加请求中间件
    新建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',
    # ... 其他中间件
]
  1. 在信号处理中获取用户
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参数更简单,不需要中间件。

  1. 视图中手动发送信号并传递用户
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')
  1. 信号处理函数接收用户参数
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:36:07