Python 从Django删除(或隐藏)默认权限

Python 从Django删除(或隐藏)默认权限,python,django,Python,Django,我正在开发一个Django应用程序,它将有两个管理后端。一个用于“普通”用户的日常使用,另一个用于更高级的任务和开发人员 应用程序使用一些自定义权限,但不使用默认权限。因此,我目前正在寻找一种删除默认权限的方法,或者至少是一种在不进行大量修改的情况下从“每日”管理员后端隐藏默认权限的方法。更新:Django 1.7支持自定义 原始答案 以下内容适用于1.7版之前的Django 这是contrib应用程序的标准功能 它处理post_syncdb信号,并为每个模型创建权限(标准3:添加、更改、删除,

我正在开发一个Django应用程序,它将有两个管理后端。一个用于“普通”用户的日常使用,另一个用于更高级的任务和开发人员


应用程序使用一些自定义权限,但不使用默认权限。因此,我目前正在寻找一种删除默认权限的方法,或者至少是一种在不进行大量修改的情况下从“每日”管理员后端隐藏默认权限的方法。

更新:Django 1.7支持自定义

原始答案

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

这是contrib应用程序的标准功能

它处理post_syncdb信号,并为每个模型创建权限(标准3:添加、更改、删除,以及任何自定义权限);它们存储在数据库的auth_权限表中

因此,每次运行syncdb管理命令时都会创建它们

你有一些选择。没有一个是真正优雅的,但您可以考虑:

  • 删除auth contrib应用程序并提供您自己的应用程序

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

  • 重写auth应用程序(内部文件)中post_syncdb信号的行为

    后果->请注意,如果没有基本权限,Django管理界面将无法工作(可能还有其他功能)

  • 删除auth_权限表中每个模型的基本权限(添加、更改、删除)(手动、使用脚本或其他方式)

    后果->您将再次失去管理员,每次运行syncdb时都需要删除管理员

  • 构建您自己的许可应用程序/系统(使用您自己的装饰程序、中间件等)或扩展现有的许可应用程序/系统

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

  • 最后一点考虑:更改contrib应用程序或Django框架本身从来都不是一件好事:如果需要升级到较新版本的Django,您可能会破坏某些东西,并且会遇到困难


    这样,如果你想尽可能干净,考虑滚动你自己的权限系统,或者扩展标准的系统(是Django权限扩展的一个很好的例子)。它不需要太多的努力,您可以按照自己觉得合适的方式构建它,克服标准django许可系统的限制。如果你做了一个好的工作,你也可以考虑开源它,让其他人使用/改进你的解决方案=)

    < P>我在同一个问题上挣扎了一段时间,我想我已经想出了一个干净的解决方案。以下是如何隐藏Django的auth应用程序的权限:

    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)
    

    当然,可以很容易地修改它以隐藏您想要的任何权限。让我知道这对你是否有效。

    阴影云提供了一个很好的概述。这里有一个简单的方法来实现你的目标

    在admin.py中添加以下行:

    from django.contrib.auth.models import Permission
    admin.site.register(Permission)
    
    您现在可以在管理员界面中添加/更改/删除权限。删除未使用的代码,当您有了所需的代码后,返回并从admin.py中删除这两行代码


    正如其他人所提到的,后续的syncdb会将所有内容放回原处。

    如果您正在创建自己的用户管理后端,并且只想显示自定义权限,则可以通过排除名称以“can”开头的权限来过滤掉默认权限

    警告: 您必须记住不要以“Can”开头命名您的权限!!!! 如果他们决定更改命名约定,这可能不起作用

    值得赞扬的是,我在项目中就是这样做的:

    from django.contrib.auth.forms import UserChangeForm
    from django.contrib.auth.models import Permission
    from django.contrib import admin    
    
    class UserEditForm(UserChangeForm):
        class Meta:
            model = User
    
            exclude = (
                       'last_login',
                       'is_superuser',
                       'is_staff',
                       'date_joined',
                       )
    
        user_permissions = forms.ModelMultipleChoiceField(
            Permission.objects.exclude(name__startswith='Can'), 
            widget=admin.widgets.FilteredSelectMultiple(_('permissions'), False))
    

    基于@pmdarrow的解决方案,我提出了一个相对干净的解决方案来修补Django管理视图

    见:


    它扩展了
    用户
    管理员以隐藏某些权限。

    您无法轻松删除这些权限(以便syncdb不会将其放回),但您可以从管理员界面隐藏这些权限。正如其他人所描述的,这个想法是覆盖管理表单,但您必须为用户和组都这样做。 以下是解决方案的admin.py文件:

    from django import forms
    from django.contrib import admin
    from django.contrib.auth.models import Permission
    from django.contrib.auth.models import User, Group
    from django.contrib.auth.admin import GroupAdmin, UserAdmin
    from django.contrib.auth.forms import UserChangeForm
    
    #
    # In the models listed below standard permissions "add_model", "change_model"
    # and "delete_model" will be created by syncdb, but hidden from admin interface.
    # This is convenient in case you use your own set of permissions so the list
    # in the admin interface wont be confusing.
    # Feel free to add your models here. The first element is the app name (this is
    # the directory your app is in) and the second element is the name of your model
    # from models.py module of your app (Note: both names must be lowercased).
    #
    MODELS_TO_HIDE_STD_PERMISSIONS = (
        ("myapp", "mymodel"),
    )
    
    def _get_corrected_permissions():
        perms = Permission.objects.all()
        for app_name, model_name in MODELS_TO_HIDE_STD_PERMISSIONS:
            perms = perms.exclude(content_type__app_label=app_name, codename='add_%s' % model_name)
            perms = perms.exclude(content_type__app_label=app_name, codename='change_%s' % model_name)
            perms = perms.exclude(content_type__app_label=app_name, codename='delete_%s' % model_name)
        return perms
    
    class MyGroupAdminForm(forms.ModelForm):
    
        class Meta:
            model = Group
    
        permissions = forms.ModelMultipleChoiceField(
            _get_corrected_permissions(),
            widget=admin.widgets.FilteredSelectMultiple(('permissions'), False),
            help_text = 'Hold down "Control", or "Command" on a Mac, to select more than one.'
        )
    
    class MyGroupAdmin(GroupAdmin):
    
        form = MyGroupAdminForm
    
    class MyUserChangeForm(UserChangeForm):
    
        user_permissions = forms.ModelMultipleChoiceField(
            _get_corrected_permissions(),
            widget=admin.widgets.FilteredSelectMultiple(('user_permissions'), False),
            help_text = 'Hold down "Control", or "Command" on a Mac, to select more than one.'
        )
    
    class MyUserAdmin(UserAdmin):
    
        form = MyUserChangeForm
    
    admin.site.unregister(Group)
    admin.site.register(Group, MyGroupAdmin)
    admin.site.unregister(User)
    admin.site.register(User, MyUserAdmin)
    

    如果要阻止Django创建权限,可以阻止发送信号

    如果在任何应用程序中将其放入management/init.py,它将在auth框架有机会之前绑定到信号处理程序(利用dispatch\u uid去抖动)


    Django 1.7中引入的一个新特性是能够定义默认权限。如中所述,如果将其设置为空,则不会创建任何默认权限

    一个有效的例子是:

    Blar1类(models.Model):
    id=models.AutoField(主键=True)
    name=models.CharField(max_length=255,unique=True,blank=False,null=False,verbose_name=“name”)
    类元:
    默认权限=()
    
    我从未尝试过,因此我不太愿意将其作为答案,但您可能可以删除它们的数据库条目。如果你的管理员用户都被归类为超级用户,那么他们被认为拥有所有权限(我认为),因此你不需要这些记录。但是没有承诺。如果他们是超级用户,则对“has permission”方法的每次调用都将返回true。但我不认为这是一个想法,因为您正在使用自定义权限。您是否阻止Django管理员检查默认权限?因为如果用户对某个对象没有任何默认权限,它就不会显示在管理中。那么,我必须和他们生活在一起。但是你不能使用更新的方法
    from django.db.models import signals
    
    def do_nothing(*args, **kwargs):
      pass
    
    signals.post_syncdb.connect(do_nothing, dispatch_uid="django.contrib.auth.management.create_permissions")
    signals.post_syncdb.connect(do_nothing, dispatch_uid="django.contrib.auth.management.create_superuser")