我面临一个奇怪的用例,我不知道如何继续。
我正在重写 DNSRecord 模型
上的 save()
方法。覆盖的主要原因是为必须在外部系统上完成的额外工作(作为保存的一部分)添加额外的副作用。附加操作包括:
从 IPAddress 模型表中获取 IPAddress 的空实例,
更新所述 IP 地址,以及
进行一系列 REST API 调用以实际在 UltraDNS 中创建 DNS 记录。
除了写入 DNSRecord
之外,这三个副作用中的每一个都可能最终失败,此时应中止保存(为了原子性)并向用户报告。
我的交易安全性下降了,但我不确定如何以有意义的方式将错误报告给用户。我读过,ValidationErrors
在这里使用并不合适,并且一些消息来源表示,最好不要在 save()
中引发
任何异常。根本没有,这似乎太严格了。我应该如何处理这些情况,既允许我提供有关错误发生原因的反馈,同时仍然优雅地失败?
请注意,我只使用管理界面。
最佳答案
我通常将此检查保留在原子 block 内,然后引发异常,看看是否可以从中获取任何内容 -
在模型中 -
def save(self, *args, **kwargs):
if self.pk is None:
....
if self.date_created is None:
.....
with transaction.atomic():
self.clean() # my personal clean method
raise Exception("This is a dummy exception") #this will automatically roll back all the save methods call hierarchy if they are also following this process, to nothing is saved
super().save()
在 View 类(Class based view)中向用户显示错误消息 -
def post(self, request, *args, **kwargs):
if form.is_valid():
....... # create the model
try:
model.save()
return self.form_valid(form)
except Exception as err:
messages.error(request, str(err))
return self.form_invalid(form)
然后在模板中将它们显示为 -
<div class="flash_message hide">
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="alert alert-{{ message.tags }}"{% endif %}>
{{ message|safe }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
注意:我使用了 Django Message Framework用于将消息从 View 传递到模板。我还使用 twitter bootstrap 3,所以我的模板的格式如下。
您还可以子类化 Exception
以添加自定义错误。
关于python - 在 Django 中,如何在 Model.save() 期间引发非验证错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26618691/