首页 > 其他分享 >Django自带的Admin后台中如何获取当前登录用户

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

时间:2023-04-12 14:32:21浏览次数:34  
标签:sender Admin request django current models kwargs 自带 Django

需求背景

在使用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后台中如何获取当前登录用户_django


标签:sender,Admin,request,django,current,models,kwargs,自带,Django
From: https://blog.51cto.com/colinspace/6185548

相关文章

  • 在django中自动删除超过10天的数据
    需求:比如过期10天的产品自动删除记录posting_date=models.DateTimeField(auto_now_add=True)#purge_old_data.pyfromdjango.core.management.baseimportBaseCommand,CommandErrorfromcus_leads.modelsimportCustomerLeadsfromdatetimeimportdatetime,timedel......
  • djangoadmin 过期显示红色字体
    参考:https://docs.djangoproject.com/en/1.8/topics/i18n/timezones/#naive-and-aware-datetime-objects起因:正常的dateime.now()得到的日期不能和Django数据库里面存储的日期数据做对比,两个解决办法:1、是把Django配置里面的USE_TZ设置成False,这样Django的数据就没有时区信息了......
  • Django框架基础(1)
    一、Django的历史1、Django是什么?  Django是使用Python语言开发的一款免费而且开源的Web应用框架。  由于Python语言的跨平台性,所以Django同样支持Windows、Linux和Mac系统。  在Python语言炽手可热的当下,Django也迅速的崛起,在Web开发领域占有一席之......
  • sqlalchemy快速插入数据,scoped_session线程安全,加载类上的装饰器,基本增删改查,django中
    今日内容sqlalchemy快速插入数据sqlalchemy是什么orm框架,跟其他web框架没有必然联系,可以独立使用安装,快速使用,执行原生sql创建表和删除表不能创建数据库不能修改字段(增加,删除)使用orm插入第一步:生成engine对象engine=create_engine("mysql+pymysql://[email protected].......
  • Django配置邮件发送
    需求用户点击忘记密码后会向邮箱发送验证码,之后用户进行验证并修改密码实现步骤登录qq邮箱,点击设置,配置配置IMAP/SMTP点击开启,之后发送短信,成功发送后会看到如下内容在settings.py文件中添加如下内容#MAILEMAIL_HOST='smtp.qq.com'EMAIL_PORT=587#或465EMAIL_......
  • Salesforce Admin管理员中文学习教程_如何高效筛选出具有Admin权限的用户!
    组织中最常见的错误之一就是拥有太多具有系统管理员简档的用户。不幸的是,这在某些行业中非常普遍。实际上这存在着很大的潜在风险。拥有这些权限的用户可能会暴露、窃取或删除组织中的数据,甚至影响到其他用户。防止过多的管理员访问权限是保护Salesforce组织的第一步。但是,仅将......
  • ZR.Admin小改和VUE3版本体验
    前言孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说:“对呀,对呀!......回字有四样写法,你知道么?”大家好,我是44岁的大龄程序员码农阿峰。阿峰从事编程二十年了,虽然没有成为架构师,却也用过很多种架构。几年前开始研究JAVA企业级快速开发框架若依,后来发现了它的.net版本......
  • Django 同一Model注册多个modelAdmin
    需求:同一个djangomodel模型,根据不同需求展示注册到admin.py中classUserMsg(models.Model):username=models.CharField(max_length=20,null=False,verbose_name='发送方')hername=models.CharField(max_length=20,null=True,verbose_name='对方姓名')ti......
  • Python Django 通用视图和错误视图的使用
    定义通用视图修改book/models.py代码中的AuthorInfo类,如果一致则不必修改classAuthorInfo(models.Model):id=models.CharField(max_length=30,verbose_name="身份证号",primary_key=True)name=models.CharField(max_length=20,verbose_name="姓名")t......
  • Django笔记二十一之使用原生SQL查询数据库
    本文首发于公众号:Hunter后端原文链接:Django笔记二十一之使用原生SQL查询数据库Django提供了两种方式来执行原生SQL代码。一种是使用raw()函数,一种是使用connection.cursor()。但是官方还是推荐在使用原生SQL之前,尽量的先去探索一下QuerySet提供的各种API。目前......