Подтвердить что ты не робот

Удалить (или скрыть) разрешения по умолчанию из Django

Я разрабатываю приложение Django, которое будет иметь два сервера поддержки. Один для ежедневного использования "обычными" пользователями и по умолчанию для более сложных задач и для разработчиков.

Приложение использует некоторые пользовательские разрешения, но ни один из стандартных. Поэтому в настоящее время я ищу способ удалить разрешения по умолчанию или, по крайней мере, способ скрыть их из "ежедневного" бэкэнда администратора без больших изменений.

4b9b3361

Ответ 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")