Django: Catching Integrity Error and showing a customized message using template

前端 未结 6 2115
梦谈多话
梦谈多话 2020-12-13 03:24

In my django powered app there is only one obvious case where \"IntegrityError\" can arise.
So, how can I catch that error and display a message using templates?

相关标签:
6条回答
  • 2020-12-13 03:52

    Just use 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})
    

    If you want you can use the message in your template.

    EDIT

    Thanks for Jill-Jênn Vie, you should use e.__cause__, as described here.

    0 讨论(0)
  • 2020-12-13 04:01

    I would validate it with ModelForm. For example:

    You got model:

    class Manufacturer(models.Model):
        name = models.CharField(default='', max_length=40, unique=True)
    

    And 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
    

    In this case when you submit name that is unique. You'll get validation error before IntegrityError. 'Category already exists' message will be shown in your form in template

    0 讨论(0)
  • 2020-12-13 04:02

    I did it like this

    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)
    

    in the template ,i can access the erroe as {{ e }}

    0 讨论(0)
  • 2020-12-13 04:08

    If you're using class-based views with the CreateView mixin, you'll want to try the call to the superclass's form_valid, for example:

    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!")
    

    You can use a template, render_to_response etc. to make the output nicer, of course.

    0 讨论(0)
  • 2020-12-13 04:09

    Just import IntegrityError

    from django.db import IntegrityError
    

    and use it inside try/Except

    try:
        //Do what is needed to be done
     except IntegrityError as e:
        //return what is supposed to be returned
    

    Thanks @Soren I just Edited my answer

    0 讨论(0)
  • 2020-12-13 04:12

    Simplest solution: write a middleware implementing process_exception that only catches IntegrityError and returns an HttpResponse with your rendered template, and make sure this middleware is after the default error handling middleware so it is called before (cf https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception for more).

    Now if I was you, I wouldn't assume such a thing as "there is only one obvious case where "IntegrityError" can arise", so I strongly recommand you do log the exception (and send email alerts) in your middleware.

    0 讨论(0)
提交回复
热议问题