咨询:Django DeleteView成功删除后添加send_mail()的正确方法
Great question! Since you're used to overriding form_valid() in CreateView for post-action tasks, let's map that logic to DeleteView—it works a bit differently but follows the same idea of hooking into the success flow.
Unlike CreateView, DeleteView doesn't rely on a form submission method like form_valid(). Its core deletion logic lives in the delete() method from the DeletionMixin, which handles fetching the object, deleting it, and redirecting to your success URL. This is the perfect spot to add your send_mail() call.
Here's the cleanest, most maintainable approach:
Step-by-Step Implementation
- First, fetch the object you're about to delete (once it's deleted, you can't access its details anymore)
- Let the parent class handle the actual deletion
- Send your email using the stored object's data
- Return the redirect response as normal
from django.views.generic.edit import DeleteView from django.core.mail import send_mail from django.urls import reverse_lazy from .models import YourTargetModel class YourModelDeleteView(DeleteView): model = YourTargetModel success_url = reverse_lazy('your-model-list-view') # Replace with your actual success URL def delete(self, request, *args, **kwargs): # Grab the object before deletion to access its details self.object = self.get_object() # Let the parent class perform the deletion response = super().delete(request, *args, **kwargs) # Send your notification email send_mail( subject=f"Item Deleted: {self.object}", message=f"The {self.object._meta.verbose_name} '{self.object}' has been successfully deleted.", from_email="notifications@yourdomain.com", recipient_list=["admin@yourdomain.com"], fail_silently=False, ) return response
Alternative (Less Intuitive) Approach
You could also override get_success_url(), but this is not ideal because this method is intended solely to return the redirect URL, not to perform side effects like sending emails. Sticking to the delete() method keeps your code aligned with Django's intended design patterns.
Pro Tip for Performance
If sending emails is a slow operation, consider offloading it to an asynchronous task queue like Celery. This way, users won't wait for the email to send before being redirected. Here's a quick example:
# In your tasks.py from celery import shared_task from django.core.mail import send_mail @shared_task def send_deletion_notification(object_id, object_name, recipient): send_mail( subject=f"Item Deleted: {object_name}", message=f"Object ID {object_id} has been deleted from the system.", from_email="notifications@yourdomain.com", recipient_list=[recipient], fail_silently=False, ) # In your DeleteView def delete(self, request, *args, **kwargs): self.object = self.get_object() response = super().delete(request, *args, **kwargs) # Pass basic details to the async task (don't pass the deleted object itself) send_deletion_notification.delay( self.object.pk, str(self.object), "admin@yourdomain.com" ) return response
内容的提问来源于stack exchange,提问作者fuser60596

