从Django中移除(或隐藏)默认权限

23 投票
9 回答
24869 浏览
提问于 2025-04-16 17:59

我正在开发一个Django应用,这个应用会有两个管理后台。一个是给“普通”用户日常使用的,另一个是默认的后台,主要用于更高级的任务和开发者使用。

这个应用使用了一些自定义的权限,但没有使用默认的权限。所以我现在在寻找一种方法,想要去掉默认的权限,或者至少能把它们隐藏起来,让“日常”管理后台看不到,而不需要做太大的改动。

9 个回答

19

我之前也遇到过这个问题,花了一段时间才找到一个简单的解决办法。下面是如何隐藏Django的认证应用中的权限的方法:

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.contrib.auth.models import Permission

class MyGroupAdminForm(forms.ModelForm):
    class Meta:
        model = MyGroup

    permissions = forms.ModelMultipleChoiceField(
        Permission.objects.exclude(content_type__app_label='auth'), 
        widget=admin.widgets.FilteredSelectMultiple(_('permissions'), False))


class MyGroupAdmin(admin.ModelAdmin):
    form = MyGroupAdminForm
    search_fields = ('name',)
    ordering = ('name',)

admin.site.unregister(Group)
admin.site.register(MyGroup, MyGroupAdmin)

当然,你可以很容易地修改这个方法,来隐藏你想要的任何权限。如果这个方法对你有用,记得告诉我哦。

21

更新:Django 1.7 支持自定义 默认权限

原始回答

以下内容适用于 Django 1.7 之前的版本

这是 auth 这个附加应用的标准功能。

它处理 post_syncdb 信号,并为每个模型创建权限(标准的三种权限:添加修改删除,以及任何自定义的权限);这些权限会存储在数据库的 auth_permission 表中。

所以,每次你运行 syncdb 管理命令时,这些权限都会被创建

你有几种选择。虽然没有一种方法特别优雅,但你可以考虑:

  1. 放弃 auth 附加应用,自己提供一个 认证后端

    后果 -> 你将失去基于 auth 用户模型构建的管理界面和其他自定义应用,但如果你的应用高度自定义,这可能是一个选择。

  2. 在 auth 应用中重写 post_syncdb 信号的行为(在 \django\contrib\auth\management__init__.py 文件中)

    后果 -> 请注意,如果没有基本权限,Django 管理界面将无法正常工作(可能还有其他功能也会受到影响)。

  3. 手动删除 auth_permission 表中每个模型的基本权限(添加修改删除),可以用脚本或其他方式。

    后果 -> 你将再次失去管理界面,并且每次运行 syncdb 时都需要手动删除这些权限。

  4. 构建自己的 权限应用/系统(使用自己的装饰器、中间件等)或扩展现有的权限系统。

    后果 -> 如果你做得好,就没有后果 - 我认为这是最干净的解决方案之一。

最后的考虑:更改附加应用或 Django 框架本身通常被认为不是好事:你可能会破坏某些功能,如果需要升级到新版本的 Django,会遇到很多麻烦。

所以,如果你想尽可能干净,考虑自己构建权限系统,或者扩展标准的权限系统(django-guardian 是一个很好的扩展示例)。这不会花费太多精力,你可以按照自己的感觉来构建,克服标准 Django 权限系统的局限性。如果你做得好,还可以考虑开源,让其他人使用和改进你的解决方案 =)

17

Django 1.7 版本新增了一个功能,可以让你定义默认的权限。根据文档的说明,如果你把这个设置为空,那么就不会创建任何默认的权限。

下面是一个可以运行的例子:

class Blar1(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255, unique = True, blank = False, null = False, verbose_name= "Name")

    class Meta:
        default_permissions = ()

撰写回答