How to add a cancel button to DeleteView in django

Michael Dunn picture Michael Dunn · Jul 16, 2013 · Viewed 11.4k times · Source

What's the best way to add a "cancel" button to a generic class-based view in Django?

In the example below, I would like the cancel button to take you to success_url without deleting the object. I have tried adding a button <input type="submit" name="cancel" value="Cancel" /> to the template. I can detect if this button was pressed by overriding the post method of the AuthorDelete class, but I can't work out how to redirect from there.

Example 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)

Example 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>

(Examples adapted from the docs)

Answer

Alasdair picture Alasdair · Jul 16, 2013

Your approach of overriding the post method and checking to see if the cancel button was pressed is ok. You can redirect by returning an HttpResponseRedirect instance.

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)

I've used get_success_url() to be generic, its default implementation is to return self.success_url.