success_message in DeleteView not shown
Asked Answered
A

6

35

I have a DeleteView:

class LectureDelete(SuccessMessageMixin, DeleteView):
model = Lecture
success_message = "Die Veranstaltung wurde gelöscht"
success_url = '/'

def get_object(self):
    qs = super(LectureDelete, self).get_object()
    if self.request.user.has_perm('edit_lecture', qs):
        return qs
    else:
        raise exceptions.PermissionDenied

And in my template to which the success_url links, I have the following code, which works fine with other messages:

{% if messages %}
        {% for message in messages %}
        <p class="alert alert-dismissable {% if message.tags %}alert-{{ message.tags }}"{% endif %}>
            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
            {{ message }}
        </p>
        {% endfor %}
    {% endif %}

But the message is not shown. Am I missing something? What am I doing worng? Thanks!

Avaria answered 18/7, 2014 at 10:11 Comment(0)
C
68

I think this issue in the Django issue tracker should answer your question.

SuccessMessageMixin hooks to form_valid which is not present on DeleteView to push its message to the user.

It also gives an alternative way which works for me:

from django.views.generic.edit import DeleteView
from django.core.urlresolvers import reverse_lazy
from django.contrib import messages
from .models import Thing

class ThingDelete(DeleteView):
    model = Thing
    success_url = reverse_lazy('list')
    success_message = "Thing was deleted successfully."

    def delete(self, request, *args, **kwargs):
        messages.success(self.request, self.success_message)
        return super(ThingDelete, self).delete(request, *args, **kwargs)

SuccessMessageMixin was not used in the delete-view (but I do use it for the Create and Update views). Hopefully this will be improved in later versions of Django (see issue for more info).

Cacodyl answered 15/8, 2014 at 10:54 Comment(3)
If there is an exception in super().delete() - e.g. the object can't be deleted bc of a FK constraint - this will still display a success message, right? Is there a way to confirm delete was a success before generating the message?Bonnibelle
@BrettThomas That's correct, if there's an exception raised in super().delete() it will still display a success message. If you switch it up and call super first then the exception will prevent the message from being stored.Ceja
Currently (Django 4.1.6), delete is never called, hook into form_valid instead.Gilbreath
P
18

The answer by Hel1 is mostly correct, but doesn't offer a solution for displaying fields within the success message, like this:

success_message = "Session %(name)s was removed successfully"

Simply get the object to be deleted and format the string with the object's dictionary, like this:

class SessionDeleteView(SuccessMessageMixin, DeleteView):
    model = Session
    success_url = reverse_lazy('session_home')
    success_message = "Session %(name)s was removed successfully"

    def delete(self, request, *args, **kwargs):
        obj = self.get_object()
        messages.success(self.request, self.success_message % obj.__dict__)
        return super(SessionDeleteView, self).delete(request, *args, **kwargs)
Polynuclear answered 7/3, 2017 at 18:53 Comment(0)
C
5
from django.contrib import messages

class LectureDelete( DeleteView):
    model = Lecture

    def get_success_url(self):
        messages.success(self.request, "deleted successfully")
        return reverse("/")
Chop answered 6/7, 2020 at 11:41 Comment(1)
This worked for me but on the last line after reverse I had to add an actual pattern name from urls.py or i'd get this error <Reverse for '/' not found. '/' is not a valid view function or pattern name>Noles
M
3

If you want to overcome the exception problem as in Brett Thomas's comment, you can update Tocino's solution in this way:

class SessionDeleteView(SuccessMessageMixin, DeleteView):
model = Session
success_url = reverse_lazy('session_home')
success_message = "Session %(name)s was removed successfully"

def delete(self, request, *args, **kwargs):
    obj = self.get_object()
    data_to_return = super(SessionDeleteView, self).delete(request, *args, **kwargs)
    messages.success(self.request, self.success_message % obj.__dict__)
    return data_to_return
Melburn answered 6/6, 2020 at 14:1 Comment(0)
W
1

If using Django 4.0.0 or above the DeleteView can be used together with SuccessMessageMixin as per this Release Note

So in the following example which deletes the a User, the success message is displayed on the account logout page after the User is deleted.

class UserDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
    success_message = _("Your account has been deleted")
    success_url = reverse_lazy('account_logout')

    def get_object(self):
        return self.request.user

Something to watch out for when upgrading from older versions of Django to Django >= 4.0.0

As per the same Release Note: Custom delete logic in delete() handlers should be moved to form_valid(). We has success messages in delete methods which stopped working after the Django 4.0.0 upgrade.

Whitted answered 25/6, 2022 at 2:23 Comment(0)
K
-1

It seems like you're using the messages framework of django in your template but not in your view.

In your view, try adding your success message like this:

from django.contrib import messages

messages.success(request, "Die Veranstaltung wurde gelöscht")
Knurl answered 18/7, 2014 at 17:33 Comment(1)
@magda is using the message framework in her view by using the SuccessMessageMixin.Cacodyl

© 2022 - 2024 — McMap. All rights reserved.