【问题标题】:Graciously handle crash while saving model via Django Admin通过 Django Admin 保存模型时优雅地处理崩溃
【发布时间】:2018-03-13 05:08:28
【问题描述】:

有时不可能知道事先并在 validator 中优雅地拒绝模型保存,这会在 Django Admin 中显示很好的错误消息。

如果在 save 操作期间发生了特定的崩溃(例如数据完整性错误),而我们仍想捕获它并显示一个不错的错误(类似于验证错误),则没有明显的方法可以做这个我能找到。

我尝试在 Django Admin 上覆盖 save_model 方法,但根据 docs,这是一件可怕的事情:

覆盖 ModelAdmin.save_model() 和 ModelAdmin.delete_model() 时,您的代码必须保存/删除对象。它们并非用于否决目的,而是允许您执行额外的操作。

那么捕获特定异常并显示漂亮错误消息的正确方法是什么?

更新:

示例:使用乐观锁定时的完整性错误。

更多具体示例django_fsm 引发的ConcurrentTransition 错误,当对象的状态自管理员加载后在 DB 中发生更改时(这可以被视为乐观锁定的轻量级版本)。

【问题讨论】:

  • 我可能错了,但是您使用 django-admin 的方式是超出其原始目的的扩展。我这么说的原因是您需要员工身份才能访问。因此,它们并不意味着支持复杂的工作流程和验证。话虽如此,它是快速原型和扩展的好方法。因此,就错误捕获而言,IMO 使用 javascript 来做到这一点。在管理员中注入自定义 js 很容易 - stackoverflow.com/questions/19910450/…。或者你可以做一个自定义的 save_model。它不是为此而构建的,但您可以构建它。
  • 您能否举例说明在验证时无法捕获但会导致完整性错误的问题?
  • @sahutchi 感谢您的意见,我知道 Django Admin 不能解决所有问题,但我觉得这并没有那么戏剧化,以至于无法由 Admin 处理。
  • @DanielRoseman 我更新了评论以提供一个具体的例子,但实际上这并不重要 - 我过去多次遇到这个问题,还有其他运行时异常。不难想象,这确实是个普遍问题。

标签: django django-admin


【解决方案1】:

我找到了一种优雅的方法来解决这个问题,而无需破解不用于否决目的的 save_model 方法。

相反,只需覆盖 change_view 和/或 add_view 并在它们崩溃时生成错误消息就足够了。

例子:

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:这个更通用的处理程序也可以从 Admin 的 AddForm 中捕获错误:

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)

【讨论】:

  • 你能详细说明一下吗?这里的MyAdmin 是什么以及在哪里定义这个函数?以及在哪里调用这个函数?
  • MyAdmin 是自定义 ModelAdmin 派生类的示例,它应该处理相关错误。您将在此类上定义/覆盖此 changeform_view(或 change_view)方法,该方法本身通常在您的 app/admin.py 模块中定义。
猜你喜欢
  • 2015-12-15
  • 1970-01-01
  • 2016-03-15
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多