在Django Admin中通过动作按钮设置is_active=False禁用用户遇问题
解决Django Admin禁用用户动作失效的问题
嘿,我来帮你排查这个问题!你的代码里有几个关键错误导致禁用用户的动作没生效,咱们一步步修正:
问题分析
- 没有使用选中的用户集合:你在
ban_users函数里硬编码了User.objects.get(username='username'),这只会去查找用户名是username的固定用户,完全没用到Admin页面选中的那些用户(也就是函数参数里的queryset) - 错误调用update方法:单个
User对象不能调用update()方法,update()是QuerySet对象的专属方法,直接对单个实例调用会抛出异常
修正后的代码
这里提供两种实现方式,按需选择:
方式一:批量更新(推荐,更高效)
直接对选中的queryset进行批量更新,不需要逐个保存:
from django.contrib import admin from django.contrib.auth.models import User from django.contrib.auth.admin import UserAdmin class MyUserAdmin(UserAdmin): list_display = ('username', 'first_name', 'last_name', 'email') readonly_fields = ('first_name', 'last_name', 'email', 'username') actions = ['ban_users'] # 修正后的禁用用户动作 def ban_users(self, request, queryset): # 直接批量更新选中的用户is_active字段 updated_count = queryset.update(is_active=False) # 给用户返回提示信息 self.message_user(request, f"成功禁用{updated_count}个用户") # 先取消默认的User admin注册,再注册自定义的MyUserAdmin admin.site.unregister(User) admin.site.register(User, MyUserAdmin)
方式二:逐个处理(适合需要额外逻辑的场景)
如果需要在禁用每个用户时执行其他操作(比如记录日志),可以逐个遍历queryset:
from django.contrib import admin from django.contrib.auth.models import User from django.contrib.auth.admin import UserAdmin class MyUserAdmin(UserAdmin): list_display = ('username', 'first_name', 'last_name', 'email') readonly_fields = ('first_name', 'last_name', 'email', 'username') actions = ['ban_users'] def ban_users(self, request, queryset): ban_count = 0 for user in queryset: user.is_active = False user.save() ban_count += 1 self.message_user(request, f"成功禁用{ban_count}个用户") admin.site.unregister(User) admin.site.register(User, MyUserAdmin)
额外说明
- 记得加上
self.message_user(),这样执行动作后会在Admin页面给用户反馈操作结果 - 原代码里的
readonly_fields写法有点冗余,不需要给每个字段加括号,直接写字段名列表就行
内容的提问来源于stack exchange,提问作者Shadowwz




