Sometimes it is not possible to know beforehand and graciously reject model save inside a validator which shows nice error message in Django Admin.
If a specific crash happens during the save operation (e.g. data integrity error) and we still want to catch it and show a nice error (similar to validation errors), there's no obvious way to do this that I could find.
I tried overriding the save_model
method on Django Admin, but this is a horrible thing to do according to the docs:
When overriding ModelAdmin.save_model() and ModelAdmin.delete_model(), your code must save/delete the object. They aren’t meant for veto purposes, rather they allow you to perform extra operations.
What's the correct way to catch specific exceptions and display nice error message then?
UPDATE:
Example: integrity error when using optimistic locking.
More concrete example: ConcurrentTransition
error raised by django_fsm
when the object's state has been changed in DB since the object was loaded by Admin (this could be considered a light version of optimistic locking).
I found an elegant way to solve this without hacking the save_model
method which is not intended for veto purposes.
Instead, it's enough to just override change_view
and/or add_view
and generate an error message if they crash.
Example:
from django.contrib import messages
from django.http import HttpResponseRedirect
def change_view(self, request, object_id, form_url='', extra_context=None):
try:
return super(MyAdmin, self).change_view(request, object_id, form_url, extra_context)
except MyException as err:
messages.error(request, err)
return HttpResponseRedirect(request.path)
edit: This more generic handler catches errors from Admin's AddForm as well:
from django.contrib import messages
from django.http import HttpResponseRedirect
def changeform_view(self, request, *args, **kwargs):
try:
return super().changeform_view(request, *args, **kwargs)
except IOError as err:
self.message_user(request, str(err), level=messages.ERROR)
return HttpResponseRedirect(request.path)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With