Django:捕获完整性错误并使用模板显示自定义消息


76

在我的django驱动的应用程序中,只有一种明显的情况会出现“ IntegrityError”。
因此,如何捕获该错误并使用模板显示消息?

Answers:


156

只需使用try and 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})

如果需要,可以在模板中使用该消息。

编辑

感谢吉尔-爵Vie的,你应该使用e.__cause__因为这里描述


谢谢,我不知道为什么“从MySQLdb导入IntegrityError”没有解决问题。调用堆栈似乎表明是库引发了错误,但它却以某种方式移到了django.db。r
朱利安

3
正如指出的V1.6的文档e.__cause__是优选的,按PEP 3134
吉尔-爵Vie的

1
如果您没有收到消息,请尝试以下操作:e.args
Jay Modi

e.message不适用于我,但是e.args [1]确实可以胜任工作
Edgar Navasardyan

@blissini-我更改了链接以指向开发文档
Tony

11

如果您将基于类的视图与CreateViewmixin一起使用,则需要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等使输出更好。


3

最简单的解决方案:编写一个process_exception仅捕获IntegrityError并返回带有呈现模板的HttpResponse的中间件实现,并确保该中间件位于默认错误处理中间件之后,因此在调用之前(参见https://docs.djangoproject.com/en / dev / topics / http / middleware /#process-exception)。

现在,如果我是您,我不会假设“只有一种明显的情况会出现“ IntegrityError””,所以我强烈建议您在中间件中记录异常(并发送电子邮件警报)。


将其放入中间件中不仅会发现应用程序中的错误,还会发现项目中的所有应用程序中的错误。
克里斯·韦瑟林

@ChrisWesseling:完全同意,这就是为什么我提到“我不会假设“只有一个明显的情况会出现“ IntegrityError”的情况””
bruno desthuilliers 2012年

1
枪不射脚,人射脚。:-)
克里斯·韦瑟林

我不会将其称为最简单的解决方案,但这是一个有用的替代方法。谢谢。
spinkus

1

我会用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之前收到验证错误。“类别已存在”消息将在模板的表单中显示


0

我是这样做的

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}}访问错误


-3

只需导入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我刚刚编辑了答案


那并不能告诉你怎么做。
索伦
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.