Ada*_*dam 11 django django-admin
我pre_save在一堆模型上有一个信号处理程序,它写入不同的数据库.如果出现问题,我想中止整个保存,或者没有向用户发送消息.
基于在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)
Run Code Online (Sandbox Code Playgroud)
这允许我从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)
Run Code Online (Sandbox Code Playgroud)
这不会干扰实际的模型保存过程,只会阻止 500 错误重定向。(请注意,这将禁用调试堆栈跟踪处理。您可以添加一些条件处理以将其重新添加)。
捕获此类错误不应该是可取的。这可能意味着您向用户暴露了敏感信息,例如有关数据库的信息(如果存在完整性错误)。由于这会绕过正常的错误处理,因此您可能还会错过通知您错误的消息。
如果需要对用户输入的错误/不完整数据进行一些检查,那么正确的方法是在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')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2999 次 |
| 最近记录: |