当前位置: 首页 > news >正文

HoRain云--DjangoAdmin获取当前用户全攻略

🎬 HoRain云小助手:个人主页

🔥 个人专栏: 《Linux 系列教程》《c语言教程》

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

🔍 核心原理:理解Django Admin的请求上下文

📋 不同场景下的获取方法

1. ModelAdmin类中获取当前用户

2. Admin表单中获取当前用户

3. Admin内联中获取当前用户

4. Admin模板中获取当前用户

5. Admin actions中获取当前用户

🎯 高级技巧:中间件传递用户信息

🔐 权限控制与用户过滤

1. 基于用户角色的数据过滤

2. 动态字段集根据用户角色

📊 用户操作日志记录

🎨 个性化Admin界面

🔧 实用工具函数

🚀 最佳实践总结


在Django Admin中获取当前用户是一个常见需求,特别是在需要根据用户权限过滤数据、记录操作日志或个性化界面时。下面我将为您提供全面的解决方案。

🔍 核心原理:理解Django Admin的请求上下文

Django Admin中获取当前用户的关键在于访问request对象。在Admin中,request对象包含了当前登录用户的user信息。

# 在任何可以访问request的地方 current_user = request.user

📋 不同场景下的获取方法

1.ModelAdmin类中获取当前用户

这是最常见的场景,您可以在ModelAdmin的各种方法中获取当前用户。

from django.contrib import admin from django.contrib.admin import ModelAdmin class MyModelAdmin(admin.ModelAdmin): # 1. 在保存模型时获取用户 def save_model(self, request, obj, form, change): # 获取当前用户 current_user = request.user # 示例:记录最后修改者 if change: obj.last_modified_by = current_user else: obj.created_by = current_user # 调用父类保存方法 super().save_model(request, obj, form, change) # 2. 在删除模型时获取用户 def delete_model(self, request, obj): # 记录删除操作 print(f"用户 {request.user.username} 删除了 {obj}") super().delete_model(request, obj) # 3. 在批量操作中获取用户 def delete_queryset(self, request, queryset): # 记录批量删除 print(f"用户 {request.user.username} 批量删除了 {queryset.count()} 条记录") super().delete_queryset(request, queryset) # 4. 在表单验证时获取用户 def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) # 可以在这里根据用户修改表单 if not request.user.is_superuser: # 非超级用户隐藏某些字段 form.base_fields['sensitive_field'].widget = forms.HiddenInput() return form # 5. 过滤查询集(根据用户权限) def get_queryset(self, request): qs = super().get_queryset(request) # 示例:普通用户只能看到自己的数据 if not request.user.is_superuser: qs = qs.filter(created_by=request.user) return qs # 6. 在change_view中获取用户 def change_view(self, request, object_id, form_url='', extra_context=None): # 添加额外上下文 extra_context = extra_context or {} extra_context['current_user'] = request.user # 记录访问日志 self.log_access(request, object_id) return super().change_view(request, object_id, form_url, extra_context) # 7. 自定义方法中获取用户 def custom_action(self, request, queryset): # 自定义批量操作 current_user = request.user for obj in queryset: obj.processed_by = current_user obj.save() self.message_user(request, f"已由 {current_user.username} 处理完成") custom_action.short_description = "自定义处理" # 辅助方法:记录访问日志 def log_access(self, request, object_id): from django.utils import timezone from myapp.models import AccessLog AccessLog.objects.create( user=request.user, action='view', model_name=self.model.__name__, object_id=object_id, timestamp=timezone.now() )

2.Admin表单中获取当前用户

在自定义的ModelForm中获取当前用户需要一些技巧,因为表单本身没有直接访问request的权限。

from django import forms from django.contrib import admin class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = '__all__' def __init__(self, *args, **kwargs): # 从kwargs中获取request self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) if self.request and self.request.user: # 根据用户角色调整表单 if not self.request.user.is_superuser: # 禁用某些字段 self.fields['approved'].disabled = True def save(self, commit=True): instance = super().save(commit=False) # 在保存时设置用户相关字段 if self.request and hasattr(instance, 'last_modified_by'): instance.last_modified_by = self.request.user if commit: instance.save() return instance class MyModelAdmin(admin.ModelAdmin): form = MyModelForm def get_form(self, request, obj=None, **kwargs): # 传递request给表单 FormClass = super().get_form(request, obj, **kwargs) class FormWithRequest(FormClass): def __new__(cls, *args, **kwargs): kwargs['request'] = request return FormClass(*args, **kwargs) return FormWithRequest

3.Admin内联中获取当前用户

在内联(InlineModelAdmin)中获取当前用户同样重要。

class MyInline(admin.TabularInline): # 或 admin.StackedInline model = RelatedModel extra = 1 def get_formset(self, request, obj=None, **kwargs): # 重写get_formset以传递request formset = super().get_formset(request, obj, **kwargs) # 保存request供后续使用 formset.request = request return formset def formfield_for_foreignkey(self, db_field, request, **kwargs): # 根据当前用户过滤外键选项 if db_field.name == "assigned_to": # 只显示当前用户所在部门的成员 if request.user.department: kwargs["queryset"] = User.objects.filter( department=request.user.department ) return super().formfield_for_foreignkey(db_field, request, **kwargs)

4.Admin模板中获取当前用户

在自定义的Admin模板中,您可以直接访问{{ request.user }}

{# 自定义change_list模板 #} {% extends "admin/change_list.html" %} {% block content %} {# 显示当前用户信息 #} <div class="user-info"> <p>当前登录用户: <strong>{{ request.user.username }}</strong></p> <p>用户组: {% for group in request.user.groups.all %} {{ group.name }}{% if not forloop.last %}, {% endif %} {% empty %} 无 {% endfor %} </p> </div> {{ block.super }} {% endblock %} {# 自定义change_form模板 #} {% extends "admin/change_form.html" %} {% block after_field_sets %} {# 根据用户角色显示不同信息 #} {% if request.user.is_superuser %} <div class="admin-note"> <h3>管理员提示</h3> <p>您正在以超级管理员身份编辑此记录。</p> </div> {% elif request.user.is_staff %} <div class="staff-note"> <p>员工操作记录将被记录。</p> </div> {% endif %} {{ block.super }} {% endblock %}

5.Admin actions中获取当前用户

在自定义的Admin actions中,request对象是直接可用的。

def make_published(modeladmin, request, queryset): """ 自定义发布操作 """ current_user = request.user # 记录操作 for obj in queryset: obj.status = 'published' obj.published_by = current_user obj.published_at = timezone.now() obj.save() # 发送通知消息 modeladmin.message_user( request, f"已由 {current_user.get_full_name()} 发布了 {queryset.count()} 个项目" ) make_published.short_description = "发布所选项目" class ArticleAdmin(admin.ModelAdmin): actions = [make_published] # 或者作为类方法 def custom_approve(self, request, queryset): """自定义批准操作""" approved_by = request.user for article in queryset: article.status = 'approved' article.approved_by = approved_by article.approved_at = timezone.now() article.save() # 记录操作日志 LogEntry.objects.log_action( user_id=request.user.id, content_type_id=ContentType.objects.get_for_model(article).pk, object_id=article.pk, object_repr=str(article), action_flag=CHANGE, change_message=f'由 {approved_by.username} 批准' ) self.message_user(request, f"已批准 {queryset.count()} 篇文章") custom_approve.short_description = "批准文章"

🎯 高级技巧:中间件传递用户信息

如果您需要在多个地方访问用户信息,可以使用中间件将其存储在threadlocal中。

# middleware.py import threading _thread_locals = threading.local() def get_current_user(): """获取当前请求的用户""" return getattr(_thread_locals, 'user', None) def get_current_request(): """获取当前请求对象""" return getattr(_thread_locals, 'request', None) class ThreadLocalMiddleware: """线程本地存储中间件""" def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 存储request和user _thread_locals.request = request _thread_locals.user = getattr(request, 'user', None) response = self.get_response(request) # 清理 for attr in ('request', 'user'): if hasattr(_thread_locals, attr): delattr(_thread_locals, attr) return response # 在settings.py中注册中间件 MIDDLEWARE = [ # ... 'myapp.middleware.ThreadLocalMiddleware', # ... ] # 现在在任何地方都可以获取当前用户 from myapp.middleware import get_current_user class MyModelAdmin(admin.ModelAdmin): def some_method(self): # 不需要request参数 current_user = get_current_user() if current_user: print(f"当前用户: {current_user.username}")

🔐 权限控制与用户过滤

1.基于用户角色的数据过滤

class SecureModelAdmin(admin.ModelAdmin): """安全模型Admin,根据用户权限过滤数据""" def get_queryset(self, request): qs = super().get_queryset(request) user = request.user # 根据用户角色应用不同过滤规则 if user.is_superuser: # 超级管理员看到所有数据 return qs elif user.is_staff: # 员工只能看到自己创建或负责的数据 return qs.filter( models.Q(created_by=user) | models.Q(assigned_to=user) ) else: # 普通用户只能看到自己的公开数据 return qs.filter( created_by=user, is_public=True ) def has_add_permission(self, request): """控制添加权限""" # 只有特定组的用户可以添加 return request.user.groups.filter(name='Editors').exists() def has_change_permission(self, request, obj=None): """控制修改权限""" if obj is None: return True # 只能修改自己的数据,除非是超级管理员 if request.user.is_superuser: return True return obj.created_by == request.user def has_delete_permission(self, request, obj=None): """控制删除权限""" if obj is None: return True # 只能删除自己的数据 return obj.created_by == request.user def has_view_permission(self, request, obj=None): """控制查看权限""" if request.user.is_superuser: return True if obj is None: return True # 检查用户是否有权查看 return self.check_view_permission(request.user, obj) def check_view_permission(self, user, obj): """自定义查看权限检查""" # 实现您的业务逻辑 if hasattr(obj, 'department'): return user.department == obj.department return False

2.动态字段集根据用户角色

class DynamicFieldsetAdmin(admin.ModelAdmin): """根据用户角色显示不同字段集""" # 基础字段集 fieldsets = [ (None, {'fields': ['title', 'content']}), ('高级选项', { 'fields': ['category', 'tags'], 'classes': ['collapse'] }), ] # 管理员字段集 admin_fieldsets = [ (None, {'fields': ['title', 'content', 'status']}), ('元数据', { 'fields': ['author', 'created_at', 'updated_at'], 'classes': ['collapse'] }), ('发布设置', { 'fields': ['publish_date', 'featured', 'allow_comments'], 'classes': ['collapse'] }), ] def get_fieldsets(self, request, obj=None): """根据用户返回不同的字段集""" if request.user.is_superuser: return self.admin_fieldsets return super().get_fieldsets(request, obj)

📊 用户操作日志记录

记录用户在Admin中的所有操作对于审计非常重要。

from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION from django.contrib.contenttypes.models import ContentType class AuditableModelAdmin(admin.ModelAdmin): """可审计的ModelAdmin,记录所有用户操作""" def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) # 记录操作日志 if change: action_flag = CHANGE message = f'修改了 {obj}' else: action_flag = ADDITION message = f'添加了 {obj}' LogEntry.objects.log_action( user_id=request.user.id, content_type_id=ContentType.objects.get_for_model(obj).pk, object_id=obj.pk, object_repr=str(obj), action_flag=action_flag, change_message=message ) def delete_model(self, request, obj): # 记录删除日志 LogEntry.objects.log_action( user_id=request.user.id, content_type_id=ContentType.objects.get_for_model(obj).pk, object_id=obj.pk, object_repr=str(obj), action_flag=DELETION, change_message=f'删除了 {obj}' ) super().delete_model(request, obj) # 在change_list中显示操作日志 def changelist_view(self, request, extra_context=None): # 获取当前用户最近的操作 recent_actions = LogEntry.objects.filter( user=request.user, content_type=ContentType.objects.get_for_model(self.model) ).order_by('-action_time')[:10] extra_context = extra_context or {} extra_context['recent_actions'] = recent_actions return super().changelist_view(request, extra_context)

🎨 个性化Admin界面

根据当前用户个性化Admin界面。

class PersonalizedAdmin(admin.ModelAdmin): """个性化Admin界面""" def changelist_view(self, request, extra_context=None): extra_context = extra_context or {} # 添加用户个性化信息 extra_context.update({ 'user_full_name': request.user.get_full_name(), 'user_groups': list(request.user.groups.values_list('name', flat=True)), 'user_permissions': list(request.user.get_all_permissions()), 'is_weekend': timezone.now().weekday() >= 5, # 周末提示 }) return super().changelist_view(request, extra_context) # 自定义模板 change_list_template = 'admin/myapp/mymodel/change_list.html' # 或者根据用户动态选择模板 def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): # 根据用户角色选择不同模板 if request.user.is_superuser: self.change_form_template = 'admin/myapp/superuser_change_form.html' elif request.user.is_staff: self.change_form_template = 'admin/myapp/staff_change_form.html' return super().render_change_form(request, context, add, change, form_url, obj)

🔧 实用工具函数

创建一些实用的工具函数来简化用户相关操作。

# utils.py from django.contrib.auth import get_user_model User = get_user_model() def get_current_user_from_request(request): """安全地获取当前用户""" if hasattr(request, 'user') and request.user.is_authenticated: return request.user return None def get_user_display_name(user): """获取用户的显示名称""" if user.get_full_name(): return user.get_full_name() return user.username def check_user_permission(user, permission_codename, model=None): """检查用户权限""" if user.is_superuser: return True if model: # 检查模型特定权限 app_label = model._meta.app_label full_permission = f"{app_label}.{permission_codename}" return user.has_perm(full_permission) return user.has_perm(permission_codename) def filter_queryset_by_user_permission(queryset, user, field_name='created_by'): """ 根据用户权限过滤查询集 """ if user.is_superuser: return queryset # 检查用户是否有查看所有的权限 if user.has_perm('myapp.view_all_records'): return queryset # 否则只返回用户自己的记录 return queryset.filter(**{field_name: user}) # 在ModelAdmin中使用 class MyModelAdmin(admin.ModelAdmin): def get_queryset(self, request): from .utils import filter_queryset_by_user_permission qs = super().get_queryset(request) return filter_queryset_by_user_permission(qs, request.user)

🚀 最佳实践总结

  1. 始终验证用户身份:在使用request.user前检查is_authenticated

  2. 使用适当的权限检查:利用Django内置的权限系统

  3. 记录重要操作:特别是数据修改和删除操作

  4. 考虑性能:避免在循环中进行数据库查询

  5. 保持代码清晰:将用户相关逻辑封装到工具函数中

  6. 测试不同用户角色:确保各种用户类型都能正常工作

  7. 使用信号处理用户相关操作:保持代码解耦

# 示例:使用信号处理用户相关操作 from django.db.models.signals import post_save from django.dispatch import receiver from django.contrib.auth.models import User @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): """用户创建时自动创建用户档案""" if created: UserProfile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): """用户保存时更新用户档案""" instance.profile.save()

通过以上方法,您可以在Django Admin中全面、安全地获取和使用当前用户信息,实现精细化的权限控制和个性化功能。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

http://www.jsqmd.com/news/458229/

相关文章:

  • 导师严选! 更贴合自考需求的AI论文网站,千笔AI VS 知文AI
  • oracle使用模版创建分区表
  • 华为OD机试真题精讲:机器人的活动区域(Python/Java/C++多语言实现)
  • AI写专著的高效之路,实用工具助力轻松完成专著创作
  • LUBTOP2025 总评榜:润滑油行业品牌实力的量化分析与参考框架
  • adc逆向数据,只含模拟部分:16bit pipleline原理图,仅供个人学习使用,适合有一...
  • 用过才敢说 9个AI论文网站深度测评,专科生毕业论文写作必备工具推荐
  • 泰凌825x之UUID代码剖析
  • 大数据的农业大棚环境数据温度预测系统设计与实现
  • 【Linux系统编程】目录和用户操作 时间函数与实例
  • HP8304@ACP#HP8304与MT3905参数对比
  • 汇川H3U带10轴(3伺服7步进)+IT6100E触摸屏项目,上下料机,7个步进加了一个4PM...
  • 增加Swap分区
  • 专科生收藏!用户挚爱的AI论文网站 —— 千笔·专业学术智能体
  • 科研人福音!AI写专著工具大推荐,让创作如行云流水般顺畅
  • 广州迅腾文化传播有限公司发布“阿处共识2.0”:深耕数字化资产管理,构建“恒温”逻辑协同生态
  • 探索自适应滤波器:从LMS算法到Simulink仿真
  • 如何在出售Windows11/10/8/7前彻底清除电脑数据
  • 信捷码垛程序(无宏密码版)
  • 系统编码规范文件Word
  • 【Gemini快速】在美国的工作场合中,一个新人如何在任何时间遇到任何人都不尴尬
  • 监控机房NTP同步时钟卫星校时电子钟实现时间戳统一
  • 本地部署 Ollama 完整指南:3 分钟让大模型在你电脑上跑起来
  • 文献检索关键词用几个最合适?给你一个可操作的范围
  • Next 10 TCP并发,数据库
  • 排序算法的终极博弈:从复杂度推导到工程选型实战
  • keil破解时报TOOLS.INI_TOOLCHAIN NOT INSTALLED解决
  • 全维度测评主流视频会议软件,精选高效协作之选
  • 【稳健之道】第二篇:Mock 的艺术 —— 隔离外部世界的“混沌”
  • Python部署卡壳工业MES?Java+YOLOv11+Spring Boot 3.4完美对接PLC!