Python 在Django Admin中捕获IntegrityError
使用Django 1.4 我希望在用户输入重复值时捕获完整性错误。此时,应用程序只显示默认的Django错误页面。(debug=True) 模型 管理 形式 此时,我得到一个错误页面,显示的是ValidationError,而不是IntegrityError。(这很有道理) 我怎样才能正确地捕获IntegrityError并将其显示在Django管理页面的顶部 更新 我注意到其中有一个表单,用于检查Python 在Django Admin中捕获IntegrityError,python,django,django-admin,Python,Django,Django Admin,使用Django 1.4 我希望在用户输入重复值时捕获完整性错误。此时,应用程序只显示默认的Django错误页面。(debug=True) 模型 管理 形式 此时,我得到一个错误页面,显示的是ValidationError,而不是IntegrityError。(这很有道理) 我怎样才能正确地捕获IntegrityError并将其显示在Django管理页面的顶部 更新 我注意到其中有一个表单,用于检查foo.parent.bar.identifier是否与foo.bar.identifier匹配
foo.parent.bar.identifier
是否与foo.bar.identifier
匹配当我从ViewAdmin中删除表单时,错误处理会按预期工作
因此,我想这里的问题是:在保存管理表单时,如何检查父项是否匹配?您不应该尝试在
save\u model
方法中处理此问题。admin视图期望save\u model
方法成功,因此不会处理完整性或验证错误。如果save\u model
方法正在引发IntegrityError
,那么问题可能在其他地方
我认为您的问题是,当您重写父类时,您忘记调用它的“clean
方法。这会阻止表单验证唯一字段。有关更多信息,请参阅
class FooForm(forms.ModelForm):
def clean(self):
cleaned_data = super(FooForm, self).clean()
parent = cleaned_data.get("parent")
...
return cleaned_data
或者某个六月会写:on_delete=models.DO_NOTHING
some = models.ForeignKey(Some, on_delete=models.DO_NOTHING)
你能展示一些重现问题的代码吗?管理员中的模型表单应验证唯一约束并显示错误消息。Django文档声明您不应该使用它来做这样的事情。您可以使用
消息
框架(Django.contrib.messages)在管理页面的顶部显示通知。@Selcuk我已经使用了消息框架,现在我被重定向到列表视图,错误消息在顶部。但是,我也收到一条消息,表示对象已保存。当我查看数据库时,该对象尚未保存。更好的解决方案是在项目的管理页面顶部显示错误消息。@Alasdair这也是我的第一个想法,但我确实得到了完整性错误。然后我认为您的代码中有一些东西没有显示给我们。您正在展示的示例不应引发IntegrityError
。我很确定这不是Django 1.4版的问题。这就是答案。谢谢。
class FooForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(FooForm, self).__init__(*args, **kwargs)
if self.instance.pk:
self.fields["parent"].queryset = Foo.objects.filter(bar=self.instance.bar)
def clean(self):
bar_identifier = self.cleaned_data.get("bar").identifier
parent = self.cleaned_data.get("parent")
if parent is not None:
parent_bar_identifier = parent.bar.identifier
if bar_identifier != parent_bar_identifier:
raise forms.ValidationError("Bar identifier should match parent Bar identifier")
return self.cleaded_data
class FooForm(forms.ModelForm):
def clean(self):
cleaned_data = super(FooForm, self).clean()
parent = cleaned_data.get("parent")
...
return cleaned_data
some = models.ForeignKey(Some, on_delete=models.DO_NOTHING)