在Django admin中保存时捕获异常?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Django admin中保存时捕获异常?相关的知识,希望对你有一定的参考价值。
我在一堆模型上有一个pre_save
信号处理程序,它写入不同的数据库。如果出现问题,我想中止整个保存,或者没有向用户发送消息。
基于Display custom message from signal in the admin,我用以下方法编写了一个mixin:
class SafeSaveMixin(object):
def save_model(self, request, *args, **kwargs):
try:
return super(SafeSaveMixin, self).save_model(request, *args, **kwargs)
except Exception as e:
self.message_user(request, e, messages.ERROR)
这允许我从pre_save
处理程序中抛出一个Exception并向用户显示该消息。问题是,即使最终跳过实际的Model.save()
,管理控制台也看不到任何内容,因此它仍然会将对象报告为已成功保存。
如果我将pre_save
处理程序更改为post_save
处理程序,那将允许基本Model.save()
发生并且至少Django将报告正确的状态,但是我在其他数据库中需要的信息是基于对象的先前状态,所以我需要在保存之前找到它。
我还考虑将错误消息填充到pre_save
中的对象本身并将其从mixin的save_model()
中拉出来 - 但这在ModelAdmin
等其他save_formset()
保存方法中变得更加复杂。
有什么好办法吗?
我想出了这个,它混入了ModelAdmin类:
class InternalModelAdminMixin:
"""Mixin to catch all errors in the Django Admin and map them to user-visible errors."""
def change_view(self, request, object_id, form_url='', extra_context=None):
try:
return super().change_view(request, object_id, form_url, extra_context)
except Exception as e:
self.message_user(request, 'Error changing model: %s' % e.msg, level=logging.ERROR)
# This logic was cribbed from the `change_view()` handling here:
# django/contrib/admin/options.py:response_post_save_add()
# There might be a simpler way to do this, but it seems to do the job.
return HttpResponseRedirect(request.path)
这不会干扰实际的模型保存过程,只会阻止500错误重定向。 (注意这将禁用调试堆栈跟踪处理。您可以添加一些条件处理来重新添加)。
抓住这种错误不应该是可取的。这可能意味着您向用户展示微妙的信息,例如关于数据库(如果存在IntegrityError)。由于这绕过了正常的错误处理,您可能还会错过通知您有关错误的消息。
如果用户输入的错误/不完整数据需要进行一些检查,那么可以在def clean(self)
中执行此操作
def clean(self):
cleaned_data = super(ContactForm, self).clean()
field_value = cleaned_data.get('field_name')
if not field_value:
raise ValidationError('No value for field_name')
以上是关于在Django admin中保存时捕获异常?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django rest 框架中捕获 Model.DoesNotExist 异常?
国际化时django.po中的msgstr =“”为中文时,django-admin.py compilemessages 出错:无效的多字节序列