Удалить (или скрыть) разрешения по умолчанию из Django
Я разрабатываю приложение Django, которое будет иметь два сервера поддержки. Один для ежедневного использования "обычными" пользователями и по умолчанию для более сложных задач и для разработчиков.
Приложение использует некоторые пользовательские разрешения, но ни один из стандартных. Поэтому в настоящее время я ищу способ удалить разрешения по умолчанию или, по крайней мере, способ скрыть их из "ежедневного" бэкэнда администратора без больших изменений.
Ответы
Ответ 1
Новая функция, введенная в 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 = ()
Ответ 2
UPDATE: Django 1.7 поддерживает настройку разрешения по умолчанию
Оригинальный ответ
Для Django до версии 1.7
допустимо следующее:
Это стандартная функциональность auth contrib.
Он обрабатывает сигнал post_syncdb и создает разрешения (стандартный 3: добавлять, изменять, удалять, а также любые пользовательские) для каждой модели; они хранятся в таблице auth_permission в базе данных.
Итак, они будут создаваться каждый раз, когда вы запускаете команду управления syncdb
У вас есть выбор. Никто не очень изящный, но вы можете подумать:
-
Снимите приложение auth contrib и предоставите собственный сервер аутентификации.
Последствия → вы потеряете админ и другие пользовательские приложения, созданные поверх модели User Auth, но если ваше приложение настроено очень хорошо, что может быть для вас вариантом
-
Переопределение поведения сигнала post_syncdb внутри приложения auth (внутри \django\contrib\auth\management__init __. py file )
Последствия → помните, что без базовых разрешений интерфейс администратора Django не сможет работать (и, возможно, другие вещи).
-
Удаление основных разрешений (добавление, изменение, удаление) для каждой модели внутри таблицы auth_permission (вручную, с помощью script или любого другого).
Последствия → , вы снова потеряете администратора, и вам нужно будет удалить их каждый раз, когда вы запустите syncdb.
-
Построение собственного приложения/системы Permission (с вашими собственными декораторами, middlewares и т.д.) или расширения существующего.
Последствия → нет, если вы его хорошо построите - это одно из самых чистых решений, на мой взгляд.
Окончательное рассмотрение: изменение приложений Contrib или самой структуры Django никогда не считается хорошей вещью: вы можете что-то сломать, и вам придется тяжело, если вам нужно будет перейти на более новую версию Django.
Итак, если вы хотите быть настолько чистым, насколько это возможно, подумайте о том, чтобы перевернуть свою собственную систему разрешений или расширить стандартную (django-guardian является хорошим примером расширения для разрешений django). Это не потребует больших усилий, и вы можете построить его так, как вам кажется правильным, преодолевая ограничения стандартной системы разрешения django. И если вы сделаете хорошую работу, вы также можете рассмотреть возможность ее открытия, чтобы другие люди использовали/улучшали ваше решение =)
Ответ 3
Я боролся с этой проблемой на некоторое время, и я думаю, что придумал чистое решение. Здесь, как вы скрываете разрешения для приложения 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)
Конечно, его можно легко изменить, чтобы скрыть любые разрешения, которые вы хотите. Сообщите мне, если это сработает для вас.
Ответ 4
ShadowCloud дал хорошее объяснение. Вот простой способ достичь своей цели.
Добавьте эту строку в свой admin.py:
from django.contrib.auth.models import Permission
admin.site.register(Permission)
Теперь вы можете добавлять/изменять/удалять разрешения в администраторе. Удалите неиспользуемые, и когда у вас есть то, что вы хотите, вернитесь назад и удалите эти две строки из admin.py.
Как уже упоминалось другими, последующий syncdb вернет все.
Ответ 5
Построенный поверх решения @pmdarrow, я придумал относительно чистое решение по исправлению представлений администратора Django.
Смотрите: https://gist.github.com/vdboor/6280390
Он расширяет администратор User
и Group
, чтобы скрыть определенные разрешения.
Ответ 6
Вы не можете легко удалить эти разрешения (так что 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)
Ответ 7
Если вы создаете свой собственный сервер управления пользователями и хотите показывать свои собственные разрешения, вы можете отфильтровывать разрешения по умолчанию, исключив разрешение с именем, которое начинается с "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))
Ответ 8
Если вы хотите запретить Django создавать разрешения, вы можете заблокировать отправку сигналов.
Если вы помещаете это в файл управления / init.py в любом приложении, он будет привязываться к обработчику сигнала, прежде чем система auth получит шанс (воспользовавшись deboun_uid debouncing).
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")