Django自带的Admin后台中如何获取当前登录用户

news2025/3/12 13:54:39

需求背景

在使用Django快速开发一个IT 电脑、显示器资产管理小系统的时候,遇到一个问题是,当变更资产设备(新增、修改、删除)的时候,能记录是谁在什么时间进行的变更。

确认的是肯定是登录状态,但是在使用Django的signal中获取不到当前登录的用户

问题演示

1、定义资产设备模型和 自定义日志模型

class Device(models.Model):
    """
    IT资产设备,主要是电脑和显示器
    """
    pass


class CustomLogEntry(models.Model):
    """日志模型,记录其他模型上的变化记录"""
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    action_time = models.DateTimeField(auto_now_add=True)
    model_name = models.CharField(max_length=100)
    model_pk = models.CharField(max_length=100)
    action = models.CharField(max_length=10)
    data = models.TextField()

    def __str__(self):
        return f"{self.user} {self.model_name} {self.action}"

2、定义信号

from django.contrib.auth.models import User
from django.contrib.admin.models import LogEntry
from django.db.models.signals import post_save
from django.dispatch import receiver

# 这里只记录Device模型的变化
# @receiver(post_save, sender=Device)
@receiver(post_save)
def log_save(sender, instance, created, **kwargs):
    print("sender: ", sender)
    action = 'CREATE' if created else 'UPDATE'
    print("current request in kwargs: ", kwargs)
    # current request in kwargs:  {'signal': <django.db.models.signals.ModelSignal object at 0x10b73d490>, 'update_fields': None, 'raw': False, 'using': 'default'}
    
    request = kwargs.get('requqest')
    print("instance: ", instance)
    print("current request in kwargs: ", request)

3、Device模型注册到admin后台,然后创建超级管理员账号,登录后台对 Device模型进行新增、修改的操作

过程日志输出如下

sender:  <class 'demoapp.models.Device'>
current request in kwargs:  {'signal': <django.db.models.signals.ModelSignal object at 0x103ec9730>, 'update_fields': None, 'raw': False, 'using': 'default'}
instance:  华为 x14 (2)
current request in kwargs:  None
sender:  <class 'django.contrib.admin.models.LogEntry'>
current request in kwargs:  {'signal': <django.db.models.signals.ModelSignal object at 0x103ec9730>, 'update_fields': None, 'raw': False, 'using': 'default'}
instance:  Changed “华为 x14 (2)” — Changed 状态.
current request in kwargs:  None

从上面的日志分析

3.1、从上面的log_save信号函数中知道,除了 sender/instance/created 之外的参数都在 kwargs 中

3.2、输出kwargs尝试获取request 我们发现是request是None,所以Django的信号中是没有request的参数的,那么就无法通过request来获取当前登录的用户

3.3、同时我们发现在未明确指定sender的情况,除了我们明确操作的Device模型之外,还多出来个 django.contrib.admin.models.LogEntry

3.4、查看 django_admin_log 表中的数据发现,Django默认是帮忙记录了各个模型的变化(可以尝试新增用户、修改用户,发现变更操作也记录到了 django_admin_log 表中去)

这里主要是研究自定义logEntry的情况下如果通过signal信号获取当前登录用户,关于 django_admin_log 记录的逻辑,我们下篇文章介绍

问题修复

查找了相关文档之后发现,django-threadlocals 模块可以很好的帮我们解决该问题

1、安装第三方模块

pip install django-threadlocals

2、配置对应的中间件

MIDDLEWARE = [
	# ... Other midddleware
	'threadlocals.middleware.ThreadLocalMiddleware',
]

3、在然后使用 threadlocals中的 `get_current_request` 

可以获取Django 后台的request,这个request中包括当前登录的user 

```python
from django.db.models.signals import post_save
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnoymousUser
from django.dispatch import receiver

from threadlocals.threadlocals import get_current_request


@receiver(post_save, sender=Device)
def log_save(sender, instance, created, **kwargs):
    if sender in [SysUser, Device]:
        request = get_current_request()
        if request:
            user = request.user
        else:
            user = AnonymousUser()
        action = 'CREATE' if created else 'UPDATE'
        data = str(instance.__dict__)
        CustomLogEntry.objects.create(user=user, model_name=sender.__name__, model_pk=instance.pk, action=action, data=data)

然后操作 Device的数据变更,然后查询 CustomLogEntry 记录,发现获取到了当前登录用户

django-admin-signal-request-user

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法学习|动态规划 LeetCode 647. 回文子串、516.最长回文子序列

动态规划一、回文子串思路实现代码二、最长回文子序列思路实现代码&#xff08;希望自己能总结出做过的动态规划题&#xff01;要开始回顾之前刷过的题了&#xff09; 一、回文子串 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。具有不同开始位置或…

回收站数据恢复的方法技巧

​最近有网友反映将一些不经常使用的文件放入回收站后忘记了&#xff0c;清空回收站后想要再次使用文件却怎么都还原不了&#xff0c;想利用回收站数据恢复软件经恢复&#xff0c;咨询有哪些回收站数据恢复软件推荐&#xff0c;下面就给大家推荐回收站数据恢复软件使用方法。 …

数据库开发重点存档

2023春数据库开发复习 T1 视图可以用的几个场景&#xff1f; 不同表字段聚合、信息重组&#xff1a;当某个查询涉及多表连接、次数频繁时&#xff0c;可以创建视图隐藏底层表的复杂性&#xff0c;简化查询。 控制权限&#xff1a;根据不同用户的权限&#xff0c;可以建立不同…

星巴克创始人第三次重出江湖

星巴克创始人第三次出山&#xff0c;与中国有关 中国咖啡连锁竞争白热化 星巴克诞生于1985年&#xff0c;爷爷级的公司 趣讲大白话&#xff1a;百年老店不容易 【趣讲信息科技135期】 **************************** 将心注入 星巴克创始人自传 创始人的激情、执行力、团队建设很…

HttpRunner3.x 源码解析(5)-runner.py

首先看下生成的pytest文件 from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCaseclass TestCaseLogin(HttpRunner):config (Config("登录成功").variables(**{"password": "tester", "expect_foo2": "co…

17_I.MX6ULL_内部RTC

目录 I.MX6U RTC简介 相关寄存器 实验源码 I.MX6U RTC简介 实时时钟是很常用的一个外设,通过实时时钟我们就可以知道年、月、日和时间等信息。因此在需要记录时间的场合就需要实时时钟,可以使用专用的实时时钟芯片来完成此功能,但是现在大多数的MCU或者MPU内部就已经自带了…

一、Locust快速 入门

1 . 介绍 Locust 是一种易于使用、可编写脚本且可扩展的性能测试工具。 您可以在常规 Python 代码中定义用户的行为&#xff0c;而不是被困在 UI 或限制性领域特定语言中。 这使得 Locust 可以无限扩展并且对开发人员非常友好。 用普通的旧 Python 编写测试场景 如果您希望…

【华为OD机试】1038 - 学英语

文章目录一、题目&#x1f538;题目描述&#x1f538;输入输出&#x1f538;样例1二、代码参考作者&#xff1a;KJ.JK&#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x…

基于价值认同的需求侧电能共享分布式交易策略(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

惊喜开箱!品牌可以从 Ledger 引领的顶级体验之一中学到什么?

Ledger 是加密货币硬件钱包的领先供应商&#xff0c;它通过进入 The Sandbox 并创建游戏化体验来扩大其教育计划&#xff0c;从而在虚拟世界中掀起波澜。通过在这个令人兴奋的新空间打造自己的品牌&#xff0c;Ledger 正在接触更广泛的受众&#xff0c;并以有趣的方式与人们互动…

回收站清空了怎么恢复?快来get实用方法!

案例&#xff1a;回收站清空了怎么恢复&#xff1f; 【真的栓Q了&#xff0c;我刚点击回收站&#xff0c;不知道按错了什么&#xff0c;回收站被清空了&#xff0c;大家有什么方法可以恢复回收站里的文件吗&#xff1f;请大家给我出出主意吧&#xff01;谢谢啦&#xff01;】 …

不愧是比亚迪!

最近这段时间&#xff0c;因为我自己准备买车嘛&#xff0c;然后先后去试驾了比亚迪汉、小鹏P7i、蔚来ET5、智己LS7这几辆车&#xff0c;接下来想分4篇文章依次给大家分享一下这四个品牌的车试驾体验。比亚迪汉小鹏P7i蔚来ET5这四个品牌总共花了三天时间&#xff0c;也算是比较…

STC89C52定时器的简介

一、序言 针对于STC89C52RC而言&#xff0c;这个芯片内部包含了三个定时器——T0、T1和T2&#xff0c;他们的中断优先级分别是1、3和5。 怎么还有一个定时器2呢&#xff1f;博主也是今天整理这篇博客的时候&#xff0c;翻阅芯片手册才发现的。如果说&#xff0c;我们经常用的…

00后面试华为软件测试工程师,竭尽全力拿到15K。。。。。

不废话&#xff0c;直接重点 一般软件测试的面试分为三轮&#xff1a;笔试&#xff0c;HR面试&#xff0c;技术面试。 前两轮&#xff0c;根据不同企业&#xff0c;或有或无&#xff0c;但最后一个技术面试是企业了解你“行不行”的关键环节&#xff0c;每个企业都会有的。 在…

从C语言到C++(第一章_C++入门_中篇)缺省参数+函数重载+引用

目录 1.缺省参数 1.1缺省参数概念 1.2缺省参数的使用&#xff1a; 1.3缺省参数的分类 1.3.1 全缺省参数 1.3.2 半缺省参数 1.4缺省参数的应用场景 2. 函数重载 2.1函数重载的概念 2.2不支持函数重载的情况 3.引用 3.1引用的概念 3.2引用的特性 3.3引用做参数 3…

C++内存管理(new和delete)

目录 1. new/delete操作内置类型 2. new和delete操作自定义类型 3. operator new与operator delete函数 4 .new和delete的实现原理 1 .内置类型 2 .自定义类型 new的原理 delete的原理 new T[N]的原理 delete[]的原理 5. 定位new表达式(placement-new) 6. malloc/f…

【JavaScript】原生js实现省市区联动效果

&#x1f609;博主&#xff1a;初映CY的前说(前端领域) ,&#x1f4d2;本文核心&#xff1a;用原生js实现省市区联动 【前言】今日在复习省市县三级联动的时候&#xff0c;有点忘了原生的js应该怎么样处理省市县的联动&#xff0c;特此写下来再次复习下 目录⭐实现思路⭐思路转…

Node【六】内置模块 【url模块与queryString】

文章目录&#x1f31f;前言&#x1f31f;url 模块&#x1f31f; URL各部分说明&#x1f31f; 将URL字符串转换为对象&#x1f31f; 将对象格式化为URL字符串&#xff1a;url.format(urlObj)&#x1f31f; URL路径处理&#xff1a;url.resolve(from, to)&#x1f31f; queryStri…

Dapr和Rainbond集成,实现云原生BaaS和模块化微服务开发

背景 Dapr 是一个开源的分布式应用运行时&#xff0c;帮助开发者构建松耦合的分布式应用程序&#xff0c;具有良好的可扩展性和可维护性。Rainbond 是一款企业级的云原生应用管理平台&#xff0c;提供了丰富的功能和工具&#xff0c;方便开发者管理和部署应用。Rainbond 和 Da…

如何通过 kubernetes ingress 或者 istio ingressgateway 来暴露 TCP 的服务

点击上方“程序猿技术大咖”&#xff0c;关注并选择“设为星标”回复“加群”获取入群讨论资格&#xff01;在 kubernetes 或 istio 应用中&#xff0c;一般都是通过 kubernetes ingress 或者 istio ingressgateway 来暴露 HTTP/HTTPS 的服务。但是在实际应用中&#xff0c;还是…