- Вопрос или проблема
- Ответ или решение
- 1. Отключение действия «Удалить выбранные»
- 2. Отключение права на удаление
- 3. Удаление ссылки «Удалить» из просмотра конкретной записи
- 4. Использование Mixin для повторного использования кода
- 5. Отключение разрешения на удаление пользователя или группы
- 6. Класс AdminSite для глобального отключения
- Заключение
Вопрос или проблема
Мне удалось отключить действие “Удалить выделенное”. Легко.
Но пользователь всё равно может кликнуть на элемент, и внизу появится красная ссылка “Удалить”.
Просто 🙂
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. Выбор правильного подхода будет зависеть от вашего конкретного случая использования и требований к доступу.