我正在开发一个有两个管理后端的Django应用程序。一个用于“普通”用户的日常使用,默认用于更高级的任务和开发人员。
应用程序使用一些自定义权限,但不使用默认权限。所以我目前正在寻找一种方法来删除默认权限,或者至少有一种方法可以将它们从“每日”管理员后端隐藏起来,而无需进行大的修改。
答案 0 :(得分:18)
更新:Django 1.7支持自定义default permissions
原始答案
以下内容适用于版本1.7之前的Django
这是auth contrib应用程序的标准功能。
它处理 post_syncdb 信号并创建权限(标准3:添加,更改,删除 ,每个型号,以及任何自定义的;它们存储在数据库的 auth_permission 表中。
因此,每次运行syncdb管理命令时都会创建
你有一些选择。没有什么是优雅的,但你可以考虑:
删除 auth contrib应用并提供您自己的authentication backend。
后果 - >您将失去在auth用户模型之上构建的管理员和其他自定义应用程序,但如果您的应用程序是高度自定义的,可以为您提供选项
覆盖auth app内部 post_syncdb 信号的行为(\django\contrib\auth\management__init__.py文件内)
后果 - >请注意,如果没有基本权限,Django管理界面将无法工作(也可能是其他工作)。
删除 auth_permission 添加,更改,删除) > table(手动,脚本或其他)。
后果 - >您将再次失去管理员,并且每次运行 syncdb 时都需要删除它们。
构建您自己的权限应用程序/系统(使用您自己的装饰器,中间件等)或扩展现有的。
后果 - >没有,如果你把它建好 - 这是我认为最干净的解决方案之一。
最后的考虑:更改contrib应用程序或Django框架本身从来都不是一件好事:如果你需要升级到更新的版本,你可能会遇到困难Django的。
所以,如果你想尽可能干净,可以考虑滚动自己的权限系统,或者扩展标准权限(django-guardian是django权限扩展的一个很好的例子)。它不会花费太多精力,您可以按照适合自己的方式构建它,克服标准django权限系统的限制。如果你做得很好,你也可以考虑开源,让其他人使用/改进你的解决方案=)
答案 1 :(得分:16)
我在这个问题上挣扎了一段时间,我想我已经找到了一个干净的解决方案。以下是隐藏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)
当然可以轻松修改它以隐藏您想要的任何权限。如果这对您有用,请告诉我。
答案 2 :(得分:10)
Django 1.7中引入的新功能是定义默认权限的能力。如documentation中所述,如果将其设置为空,则不会创建任何默认权限。
一个工作的例子是:
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 = ()
答案 3 :(得分:5)
ShadowCloud给出了一个很好的破坏。这是实现目标的简单方法。
在admin.py中添加以下内容:
from django.contrib.auth.models import Permission
admin.site.register(Permission)
您现在可以在管理员中添加/更改/删除权限。删除未使用的那些,当你有你想要的东西时,返回并从admin.py中删除这两行。
正如其他人所提到的,后续的syncdb会把所有东西都放回去。
答案 4 :(得分:2)
在@pmdarrow的解决方案的基础上,我提出了一个相对干净的解决方案来修补Django管理员视图。
请参阅:https://gist.github.com/vdboor/6280390
它扩展了User
和Group
管理员以隐藏某些权限。
答案 5 :(得分:2)
您无法轻松删除这些权限(以便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)
答案 6 :(得分:0)
如果您要创建自己的用户管理后端,并且只想显示自定义权限,则可以通过排除名称以“Can”开头的权限来过滤掉默认权限。
警告: 你必须记住不要以“Can”开头命名你的权限!!!! 如果他们决定更改命名约定,则可能无效。
归功于pmdarrow,这就是我在项目中的表现:
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))
答案 7 :(得分:0)
如果您想阻止Django创建权限,您可以阻止发送信号。
如果你在任何应用程序中将它放入管理/ init .py,它将在auth框架有机会之前绑定到信号处理程序(利用dispatch_uid去抖动)。
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")