根据has_delete_permission的文档字符串 https://github.com/django/django/blob/1.9.7/django/contrib/admin/options.py#L448-L461:
def has_delete_permission(self, request, obj=None):
"""
Returns True if the given request has permission to change the given
Django model instance, ...
"""
这意味着has_delete_permission
按请求执行,而不是按对象执行。在批量操作中,obj
未设置。但是您可以检查request
:
def has_delete_permission(self, request, obj=None):
if request.POST and request.POST.get('action') == 'delete_selected':
return '1' not in request.POST.getlist('_selected_action')
return obj is None or obj.pk != 1
请注意,上述之所以有效,是因为the delete_selected action takes has_delete_permission考虑到 https://github.com/django/django/blob/1.9.7/django/contrib/admin/actions.py#L29.
您可能还需要提供有关该错误的一些详细信息:
from django.contrib import messages
def has_delete_permission(self, request, obj=None):
if request.POST and request.POST.get('action') == 'delete_selected':
if '1' in request.POST.getlist('_selected_action'):
messages.add_message(request, messages.ERROR, (
"Widget #1 is protected, please remove it from your selection "
"and try again."
))
return False
return True
return obj is None or obj.pk != 1
I guess has_delete_permission
出于性能原因,按请求而不是按对象调用。一般情况下,做一个是没有用的SELECT
查询并循环has_delete_permission
(根据它的作用,这可能会很耗时)在运行之前DELETE
询问。当需要这样做时,开发人员需要采取必要的步骤。