Задать вопрос
@exctac

Django: как установить запрет на удаление объекта через админку?

Добрый день.

Хочу после нажатия на кнопку удалить в админке, сделать кое-какую "проверку", если проверка верна то запись удаляем, если нет то возвращаем на ту же страницу с ошибкой (на подобии ValidationError), где выводится сообщение аля "запись не может быть удалена потому что ...".
В admin.ModelAdmin есть метод has_delete_permission, пока использую его, он отвечает за отображение кнопки "удалить":
def has_delete_permission(self, request, obj=None):
        if obj:
            a = 1 
            if a:
                return True
        return False

Но это не совсем то что мне надо, я хочу чтоб кнопка была всегда, а разрешение на удаление или нет было после ее нажатия. Валидация формы работает именно по такому принципу.

Можно и так сделать:
def delete_model(self, request, obj):
        if True:
            obj.delete()
        else:
            raise Exception

Но, таким образом от просто выкидывает страницу ошибки, а не страницу редактирования записи с ошибкой, к тому же delete_model как и save нельзя использовать для блокирования удаления объекта, только для добавления действий до и после удаления.

Спасибо за участие!
  • Вопрос задан
  • 1320 просмотров
Подписаться 2 Простой 1 комментарий
Решения вопроса 1
@javedimka
Хочу сока
к тому же delete_model как и save нельзя использовать для блокирования удаления объекта, только для добавления действий до и после удаления.

Это абсолютно не верно. Модель будет удалена если при переопределении этого метода явно вызвать super().delete_model(request, obj), иначе - нет.
Можно сделать так чтобы messages framework не захватывал стандартное сообщение об успешном удалении которое посылается админкой с промежуточной страницы и добавить свое:

from django.contrib import messages


def delete_model(self, request, obj):
    """Если какая-то проверка успешна - удалить объект, если нет, то показать сообщение об ошибке."""
    if check_permission(obj):
        return super().delete_model(request, obj)
    # При следующем запросе захватываем только ошибки.
    # Так после нажатия на кнопку удаления не будет захвачено ложное сообщение
    # об успешном удалении.
    messages.set_level(request, messages.ERROR)
    message = "You cant delete this!"
    # Посылаем свое сообщение об ошибке.
    self.message_user(request, message, level=messages.ERROR)


Ну еще сделать что-то с логированием, потому что "удаление" все равно попадет в "недавние действия" на главной странице админки, хоть объект и не был удален.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы