Python 从Django删除(或隐藏)默认权限
我正在开发一个Django应用程序,它将有两个管理后端。一个用于“普通”用户的日常使用,另一个用于更高级的任务和开发人员Python 从Django删除(或隐藏)默认权限,python,django,Python,Django,我正在开发一个Django应用程序,它将有两个管理后端。一个用于“普通”用户的日常使用,另一个用于更高级的任务和开发人员 应用程序使用一些自定义权限,但不使用默认权限。因此,我目前正在寻找一种删除默认权限的方法,或者至少是一种在不进行大量修改的情况下从“每日”管理员后端隐藏默认权限的方法。更新:Django 1.7支持自定义 原始答案 以下内容适用于1.7版之前的Django 这是contrib应用程序的标准功能 它处理post_syncdb信号,并为每个模型创建权限(标准3:添加、更改、删除,
应用程序使用一些自定义权限,但不使用默认权限。因此,我目前正在寻找一种删除默认权限的方法,或者至少是一种在不进行大量修改的情况下从“每日”管理员后端隐藏默认权限的方法。更新:Django 1.7支持自定义 原始答案 以下内容适用于1.7版之前的Django 这是contrib应用程序的标准功能 它处理post_syncdb信号,并为每个模型创建权限(标准3:添加、更改、删除,以及任何自定义权限);它们存储在数据库的auth_权限表中 因此,每次运行syncdb管理命令时都会创建它们 你有一些选择。没有一个是真正优雅的,但您可以考虑:
这样,如果你想尽可能干净,考虑滚动你自己的权限系统,或者扩展标准的系统(是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")