Django DeleteView without confirmation template

Question:

I am using Django DeleteView in a template and I’ve created a url & view.
Is it possible to skip the process of loading the _confirm_delete template and just post the delete immediately.

Asked By: yaniv14

||

Answers:

Yes, just change the next parameter. In your return response, make sure that the dictionary that you pass in is has something like this : { 'next': '/<your_path_here>}/' }, make sure you commit the changes before adding the next parameter. You might want to change your view’s get and post functions.

Answered By: Games Brainiac

DeleteView responds to POST and GET requests, GET request display confirmation template, while POST deletes instance.

You can send POST request, without confirmation with form like this:

<form method="POST" action="{% url "your_delete_url_name" %}">
   {% csrf_token %}<input type="submit" value="DELETE">
</form>

If you do not want to have a link instead form button, use some javascript to make invisible form, that will be submitted on link click.

It is not good practice to use GET request for updating or deleting, but if you really insist you can shortcut get method in your class view to post, ie:

def get(self, *args, **kwargs):
    return self.post(*args, **kwargs)
Answered By: bmihelac

Or you can redefine get() method in your DeleteView:

class YourDeleteView(DeleteView):

    model = YourModel
    success_url = '<success_url>'

    def get(self, request, *args, **kwargs):
        return self.post(request, *args, **kwargs)

But be careful with that, ensure that this doesn’t affect other functionality.

Answered By: AmirM

All you have to do is override the get_success_url method of your delete view. Then it will directly delete the object from the DB. Eg:

class YourView(DeleteView):
    model = YourModel

    def get_success_url(self):
        return reverse('your_redirect_view')
Answered By: Krishna G Nair

Or you could only allow HTTP request method delete by routing the request directly to the delete method of your class.

from django.views.generic import DeleteView
from django.http import HttpResponseForbidden

class PostDeleteView(DeleteView):
    model = Post
    http_method_names = ['delete']

    def dispatch(self, request, *args, **kwargs):
        # safety checks go here ex: is user allowed to delete?
        if request.user.username != kwargs['username']:
            return HttpResponseForbidden()
        else:
            handler = getattr(self, 'delete')
            return handler(request, *args, **kwargs)

    def get_success_url(self):
        username = self.kwargs.get('username')
        success_url = str(reverse_lazy('post:user_home', kwargs={'username': username}))
        return success_url

Let’s say your URL looks like this:

path('posts/delete/<int:pk>/', PostDeleteView.as_view(), name='post_delete'),

For clarity why this works, you have to analyze the post and delete methods.

def post(self, request, *args, **kwargs):
    return self.delete(request, *args, **kwargs)

def delete(self, request, *args, **kwargs):
    """
    Call the delete() method on the fetched object and then redirect to the
    success URL.
    """
    self.object = self.get_object()
    success_url = self.get_success_url()
    self.object.delete()
    return HttpResponseRedirect(success_url)

post just calls delete and delete gets the object and success URL, deletes the object, then redirects to the success URL you provided. pk_url_kwarg = 'pk' is why I showed the <int:pk> part in the URL.

Answered By: Jarad

You can override the get() method to behave exactly like the delete() method:

def get(self, request, *args, **kwargs):
  return self.delete(request, *args, **kwargs)

See CCBV here: https://ccbv.co.uk/projects/Django/4.1/django.views.generic.edit/DeleteView/

Answered By: Aaron C. de Bruyn
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.