如何在Django管理界面中防止超级用户删除?

8
在Django admin中,我有4个用户和一个超级用户。我有一些带有员工状态的用户,他们具有有限的访问权限,无法删除/查看/编辑其他用户,但管理员对其他所有用户和模型都具有授权。我希望超级用户能够访问用户数据并编辑/修改/删除它们,但我不希望超级用户能够删除自己。目前,超级用户可以删除自己。在Django中是否有一种禁用超级用户删除自己的方法?谢谢。

1
你可以覆盖 User 模型的管理员并在检测到超级用户试图删除自己时引发异常。 - Thomas Orozco
2个回答

14

不要使用has_delete_permission()覆盖,因为在从更改列表执行删除操作时,它不会在每个对象上被调用。

使用信号来完成。将此添加到任何models.py中。

from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied

@receiver(pre_delete, sender=User)
def delete_user(sender, instance, **kwargs):
    if instance.is_superuser:
        raise PermissionDenied

这种方法唯一的缺点是没有人能够删除任何超级用户。在删除之前,您必须将用户属性“is_superuser”设置为False。


是的,谢谢,它对我很有效...最后如果超级用户试图删除自己,它会显示403禁止访问。 - bor

2
您可以尝试覆盖 UserAdmin,以使其不允许删除,具体文档请参见这里
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

class MyUserAdmin(UserAdmin):

    def has_delete_permission(self, request, obj=None):
       if obj is None:
           return True
       else:
           return not obj.is_superuser

admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

似乎Django只调用此函数来确定是否显示“删除”按钮。当您从列表中选择用户并一次删除多个时,将使用obj=None调用该函数。您可以通过在obj=None时返回False来抑制从列表中删除,或者通过覆盖queryset函数(在Django 1.6中为get_queryset)来隐藏超级用户。 - augustomen
是的,这就是我想表达的意思 ;) - Simanas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接