Django 1.11 admin忽略has_delete_permission,员工用户无法删除对象
问题分析与解决方案
我之前也碰到过类似的问题,在Django 1.11里批量删除的权限逻辑和单个删除确实有点不一样,让我给你拆解一下原因和解决办法:
问题根源
你在MyModelAdmin里重写的has_delete_permission方法,只对单个对象的删除操作生效。但当你使用「删除所选」进行批量删除时,Django默认的delete_selected动作会直接检查用户是否拥有该模型的全局delete权限(对应数据库auth_permission表中的记录),并不会调用你重写的权限方法——这就是为什么你会看到那个权限提示的核心原因。
解决方案
方案一:直接给员工用户分配删除权限
这是最简单的解决方式,适合不需要复杂权限逻辑的场景:
- 登录Django admin,进入「用户」管理页面,找到对应的员工用户
- 编辑该用户,在「权限」区域,找到
MyModel对应的**「删除 my model」**权限(格式通常是[你的app名] | my model | 删除 my model),勾选该权限 - 保存后,用户即可正常进行批量删除操作,单个对象删除也会因为你重写的方法保持可用
方案二:自定义批量删除动作(适配你的权限逻辑)
如果你不想给用户分配全局删除权限,希望统一通过has_delete_permission来控制权限,可以自定义批量删除动作替换默认的:
from django.contrib.admin.actions import delete_selected from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import PermissionDenied @admin.register(MyModel) class MyModelAdmin(admin.ModelAdmin): def has_add_permission(self, request): return True def has_change_permission(self, request, obj=None): return True def has_delete_permission(self, request, obj=None): return True # 自定义批量删除动作 def custom_delete_selected(self, request, queryset): # 用我们重写的权限方法检查权限 if not self.has_delete_permission(request): raise PermissionDenied # 执行默认的删除逻辑 delete_selected(self, request, queryset) custom_delete_selected.short_description = _("删除所选 my model") # 替换默认的删除动作 actions = [custom_delete_selected]
这样批量删除时,就会调用你重写的has_delete_permission来校验权限,不再依赖用户的全局权限设置。
额外验证
如果单个对象删除也出现问题,那可以检查:
- 员工用户是否开启了「Staff status」(你说能创建编辑,这个应该没问题)
- 是否有其他自定义的权限中间件或信号干扰了权限判断
内容的提问来源于stack exchange,提问作者Vitaly Trifanov
相关产品推荐
相关产品推荐

