Как отключить ссылку “Удалить” в Django Admin

Вопрос или проблема

Мне удалось отключить действие “Удалить выделенное”. Легко.

Но пользователь всё равно может кликнуть на элемент, и внизу появится красная ссылка “Удалить”.

Просто 🙂

class DeleteNotAllowedModelAdmin(admin.ModelAdmin):
    # Другие настройки здесь
    def has_delete_permission(self, request, obj=None):
        return False

Если вы хотите отключить конкретное действие, которое не является пользовательским, сделайте это. В django 1.6.6 мне пришлось расширить get_actions, а также определить has_delete_permission. Решение с has_delete_permission не убирает действие из выпадающего списка для меня:

class MyModelAdmin(admin.ModelAdmin):

    ....

    def get_actions(self, request):
        # Отключаем удаление
        actions = super(MyModelAdmin, self).get_actions(request)
        del actions['delete_selected']
        return actions

    def has_delete_permission(self, request, obj=None):
        # Отключаем удаление
        return False

Не включая его в actions = ['your_custom_action'], это работает только для пользовательских действий (defs), которые вы определили для этой модели. Решение AdminSite.disable_action('delete_selected') отключает его для всех моделей, поэтому вам придется явно включать их позже для каждого modelAdmin.

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

Вы, вероятно, используете:

AdminSite.disable_action('delete_selected')

Для большего контроля просто реализуйте свой собственный админ и установите его действия на то, что вам нужно:

class MyModelAdmin(admin.ModelAdmin):
    actions = ['whatever', 'actions']

Ссылка: http://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/#disabling-a-site-wide-action

Решения здесь уже неплохие, но я предпочитаю иметь это в виде переиспользуемого миксина, как это:

class NoDeleteAdminMixin:
    def has_delete_permission(self, request, obj=None):
        return False

Вы можете использовать это во всех своих администраторах, где хотите предотвратить удаление, следующим образом:

class MyAdmin(NoDeleteAdminMixin, ModelAdmin):
    ...

admin.site.disable_action('delete_selected')

Из документации

Это очень старая информация, но всё же она может помочь кому-то.

Предполагая, что OP

… пользователь всё равно может кликнуть на элемент, и внизу появится красная ссылка “Удалить”.

имеет в виду красную кнопку в представлении “изменить”. Эту кнопку можно убрать, расширив метод ModelAdmin.change_view следующим образом:

def change_view(self, request, object_id=None, form_url="", extra_context=None):
    return super().change_view(request, object_id, form_url,
                               extra_context=dict(show_delete=False))

Вы можете сделать то же самое с show_save и show_save_and_continue. Более подробную информацию и альтернативы можно найти здесь.

Также обратите внимание, что, начиная с версии 2.1, Django имеет отдельное has_view_permission (документация), что может быть лучшим вариантом, в зависимости от вашего случая использования.

Ответ или решение

В Django Admin отключение ссылки «Удалить» можно реализовать несколькими способами. Ниже приведены методы, позволяющие полностью убрать возможность удаления записей как на уровне действий (первичный доступ к списку), так и на уровне просмотра конкретной записи.

1. Отключение действия «Удалить выбранные»

Первый шаг — отключить функцию удаления из набора действий в админке. Вы можете переопределить метод get_actions в вашем админском классе:

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):

    def get_actions(self, request):
        actions = super().get_actions(request)
        if 'delete_selected' in actions:
            del actions['delete_selected']
        return actions

    def has_delete_permission(self, request, obj=None):
        return False

2. Отключение права на удаление

Чтобы гарантировать, что у пользователей нет прав на удаление, вы можете переопределить метод has_delete_permission, который по умолчанию возвращает разрешение на удаление:

class MyModelAdmin(admin.ModelAdmin):
    def has_delete_permission(self, request, obj=None):
        return False

3. Удаление ссылки «Удалить» из просмотра конкретной записи

Если вы хотите убрать кнопку «Удалить» из формы редактирования записи, вы можете переопределить метод change_view:

def change_view(self, request, object_id=None, form_url="", extra_context=None):
    return super().change_view(request, object_id, form_url,
                               extra_context={'show_delete': False})

4. Использование Mixin для повторного использования кода

Если вы хотите сделать код более удобным для повторного использования, создайте миксин:

class NoDeleteAdminMixin:
    def has_delete_permission(self, request, obj=None):
        return False

class MyAdmin(NoDeleteAdminMixin, admin.ModelAdmin):
    pass

5. Отключение разрешения на удаление пользователя или группы

Кроме того, вы можете отключить разрешение на удаление для конкретного пользователя или группы, просто убрав у них разрешение yourapp.delete_yourmodel. Это можно сделать через интерфейс Django Admin.

6. Класс AdminSite для глобального отключения

Если вы хотите удалить действие «Удалить выбранные» для всех моделей, вы можете использовать метод disable_action:

from django.contrib import admin

admin.site.disable_action('delete_selected')

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

Заключение

Эти методы позволяют вам полностью отключить возможность удаления для конкретных моделей в Django Admin. Выбор правильного подхода будет зависеть от вашего конкретного случая использования и требований к доступу.

Оцените материал
Добавить комментарий

Капча загружается...