I'm using Django 5.0.3. I have a job listings app, with a DeleteListingView. I want to override the delete() method, so that I can use messages.success() to send a message to the success url's template once a listing is deleted.
However, the delete() method isn't being overridden. A listing gets deleted, and I'm redirected to the correct url, but the message isn't sent. I've even tried to add a print() statement inside delete() to see if it appears in cmd, but it doesn't.
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.urls import reverse_lazy
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from .models import Listings
class ListingsListView(ListView):
model = Listings
template_name = 'listings/listings_list.html'
context_object_name = 'listings'
class DeleteListingView(LoginRequiredMixin, DeleteView):
model = Listings
template_name = 'listings/listing_delete.html'
context_object_name = 'listing'
success_url = reverse_lazy('listings')
def delete(self, request, *args, **kwargs):
listing = self.get_object()
listing_title = listing.job_title
messages.success(self.request, f"Listing titled '{listing_title}' was deleted successfully.")
print(f"delete() has been overridden successfully.") # To appear in cmd
return super().delete(request, *args, **kwargs)
and in listings_list.html template:
{% for message in messages %}
<p> {{ message }}</p>
{% endfor %}
Nothing I've tried is working, and I can't seem to find a solution anywhere. What am I missing?
#Update: After research, even using ChatGPT, I still can't make the custom delete() method execute. I've tried a function-based view, and it worked. The messages.success() was executed accordingly, and displayed in the success_url's template. Here's the view:
def delete_item(request, pk):
listing = get_object_or_404(Listings, pk=pk)
if request.method == 'POST':
listing_title = listing.job_title
listing.delete()
messages.success(request, f"Listing titled '{listing_title}' was deleted successfully.")
return redirect(reverse('listings'))
return render(request, 'listings/listing_delete.html', {'listing': listing})
Since Django 4.0 DeleteView
uses the FormMixin
and hence depends on the form_valid
method instead. As a consequence it now also supports the SuccessMessageMixin which you should use:
from django.contrib.messages.views import SuccessMessageMixin
class DeleteListingView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
model = Listings
template_name = 'listings/listing_delete.html'
context_object_name = 'listing'
success_url = reverse_lazy('listings')
success_message = "Listing titled '%(title)s' was deleted successfully."
def get_success_message(self, cleaned_data):
return self.success_message % dict(
cleaned_data,
title=self.object.job_title,
)