Как добавить кнопку отмены в DeleteView в django

Какой лучший способ добавить кнопку "Отменить" к универсальному представлению на основе класса в Django?

В приведенном ниже примере я хотел бы, чтобы кнопка отмены перенесла вас на success_url без удаления объекта. Я попытался добавить в шаблон кнопку <input type="submit" name="cancel" value="Cancel" />. Я могу определить, была ли эта кнопка нажата, переопределив метод post класса AuthorDelete, но я не могу решить, как перенаправлять оттуда.

Пример myapp/views.py:

from django.views.generic.edit import DeleteView
from django.core.urlresolvers import reverse_lazy
from myapp.models import Author

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

    def post(self, request, *args, **kwargs):
        if request.POST["cancel"]:
            return ### return what? Can I redirect from here?
        else:
            return super(AuthorDelete, self).post(request, *args, **kwargs)

Пример myapp/author_confirm_delete.html:

<form action="" method="post">{% csrf_token %}
    <p>Are you sure you want to delete "{{ object }}"?</p>
    <input type="submit" value="Confirm" />
    <input type="submit" name="cancel" value="Cancel" /> 
</form>

(Примеры, адаптированные из docs)

Ответ 1

Ваш подход к переопределению метода post и проверка правильности нажатия кнопки отмены. Вы можете перенаправить, вернув экземпляр HttpResponseRedirect.

from django.http import HttpResponseRedirect

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

    def post(self, request, *args, **kwargs):
        if "cancel" in request.POST:
            url = self.get_success_url()
            return HttpResponseRedirect(url)
        else:
            return super(AuthorDelete, self).post(request, *args, **kwargs)

Я использовал get_success_url() как общий, его реализация по умолчанию - возврат self.success_url.

Ответ 2

Почему бы вам просто не поместить ссылку "Отменить" на success_url вместо кнопки? Вы всегда можете создать стиль с помощью CSS, чтобы он выглядел как кнопка.

Это имеет то преимущество, что вы не используете форму POST для простого перенаправления, что может смутить поисковые системы и разбить веб-модель. Кроме того, вам не нужно изменять код Python.

Ответ 3

При использовании CBV вы можете получить доступ к view непосредственно из шаблона

<a href="{{ view.get_success_url }}" class="btn btn-default">Cancel</a>

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

Это отмечено в Документы ContextMixin

Шаблонный контекст всех общих представлений на основе классов включает viewпеременная, указывающая на экземпляр View.