How to add a cancel button to DeleteView in django
Asked Answered
M

6

20

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)

Manton answered 16/7, 2013 at 14:3 Comment(0)
P
21

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.

Peril answered 16/7, 2013 at 14:13 Comment(0)
H
16

Why don't you simply put a "Cancel" link to the success_url instead of a button? You can always style it with CSS to make it look like a button.

This has the advantage of not using the POST form for simple redirection, which can confuse search engines and breaks the Web model. Also, you don't need to modify the Python code.

Highroad answered 17/7, 2013 at 10:25 Comment(2)
Those are good arguments for this approach. But to do it I'd have to add the success_url to the template context, so I would still have to modify the python code a bit.Manton
@MichaelDunn Actually you can access the url address via {{ view.success_url }} , so there should not be extra python codeAchernar
H
12

If using CBV's you can access the view directly from the template

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

Note: you should access it through the getter in case it has been subclassed.

This is noted in the ContextMixin docs

The template context of all class-based generic views include a view variable that points to the View instance.

Heterogamy answered 25/5, 2017 at 13:39 Comment(0)
G
1

Having an element of type button, will not send a POST request. Therefore, you can use this to do a http redirection like this:

<button type="button" onclick="location.href='{{ BASE_URL }}replace-with-url-to-redirect-to/'">Cancel</button>
Greenbrier answered 17/5, 2021 at 4:24 Comment(0)
R
0

This is probably the easiest way to do what OP asks:

<input type="submit" value="Confirm" />
* <a href="{% url 'success_url' %}"><button type="button">Cancel</button></a>
Receiptor answered 5/4, 2023 at 9:36 Comment(0)
A
-1

Do you even need the get_success_url, why not just use:

Cancel

and go to any other url you want?

Antaeus answered 12/2, 2019 at 15:40 Comment(1)
The benefit of using get_success_url is that it takes the user to a destination that makes sense, in the context of pressing the cancel button. This is particularly important when you are re-using a view to handle several different types of objects.Bienne

© 2022 - 2024 — McMap. All rights reserved.