【发布时间】:2012-07-02 12:07:15
【问题描述】:
在我的 django 应用程序中,只有一种明显的情况会出现“IntegrityError”。
那么,我如何才能捕获该错误并使用模板显示消息?
【问题讨论】:
在我的 django 应用程序中,只有一种明显的情况会出现“IntegrityError”。
那么,我如何才能捕获该错误并使用模板显示消息?
【问题讨论】:
只需使用 try 和 catch。
from django.db import IntegrityError
from django.shortcuts import render_to_response
try:
# code that produces error
except IntegrityError as e:
return render_to_response("template.html", {"message": e.message})
如果您愿意,可以使用模板中的消息。
编辑
感谢Jill-Jênn Vie,您应该使用e.__cause__、as described here。
【讨论】:
e.__cause__ 是首选,根据PEP 3134。
如果您使用带有CreateView mixin 的基于类的视图,您需要通过try 调用超类的form_valid,例如:
from django.db import IntegrityError
...
class KumquatCreateView(CreateView):
model = Kumquat
form_class = forms.KumquatForm
...
def form_valid(self, form):
...
try:
return super(KumquatCreateView, self).form_valid(form)
except IntegrityError:
return HttpResponse("ERROR: Kumquat already exists!")
当然,您可以使用模板、render_to_response 等来使输出更好。
【讨论】:
最简单的解决方案:编写一个实现 process_exception 的中间件,它只捕获 IntegrityError 并使用渲染的模板返回一个 HttpResponse,并确保此中间件位于默认错误处理中间件之后,因此在之前调用它(参见 https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception 了解更多信息)。
现在,如果我是你,我不会假设“只有一种明显的情况会出现“IntegrityError””,所以我强烈建议你在你的文件中记录异常(并发送电子邮件警报)中间件。
【讨论】:
我会用 ModelForm 来验证它。例如:
你有模型:
class Manufacturer(models.Model):
name = models.CharField(default='', max_length=40, unique=True)
和ModelForm:
class ManufacturerForm(forms.ModelForm):
def clean(self):
cleaned_data = super(ManufacturerForm, self).clean()
name = cleaned_data.get('name')
if Manufacturer.objects.filter(name=name).exists():
raise forms.ValidationError('Category already exists')
class Meta:
model = Manufacturer
在这种情况下,当您提交唯一的名称时。您将在 IntegrityError 之前收到验证错误。 “类别已存在”消息将显示在模板中的表单中
【讨论】:
我是这样做的
from django.db import IntegrityError
from django.shortcuts import render
from .models import Person
from .forms import PersonForm
class PersonView(View):
def get(self, request):
pd = PersonForm()
return render(request, "app1/my_form.html", context={ 'form': pd })
def post(self, request):
pd = PersonForm(request.POST)
if pd.is_valid():
name = pd.cleaned_data['name']
age = pd.cleaned_data['age']
height = pd.cleaned_data['height']
p = Person()
p.name = name
p.age = age
p.height = height
try:
p.save()
except IntegrityError as e:
e = 'this data already exists in the database'
return render(request, "app1/my_form.html", context={ 'form': pd, 'e': e})
context = {
'person': {
'name': name,
'age': age,
'height': height,
},
'form': pd
}
else:
print("Form is invalid")
context = { 'form': pd }
return render(request, "app1/my_form.html", context=context)
在模板中,我可以访问错误为 {{ e }}
【讨论】:
只需导入 IntegrityError
from django.db import IntegrityError
并在 try/Except 中使用它
try:
//Do what is needed to be done
except IntegrityError as e:
//return what is supposed to be returned
感谢@Soren,我刚刚编辑了我的答案
【讨论】: