Django: виявлення помилки цілісності та показ налаштованого повідомлення за допомогою шаблону


77

У моїй програмі, що працює від django, є лише один очевидний випадок, коли може виникнути "IntegrityError".
Отже, як я можу виявити цю помилку та відобразити повідомлення за допомогою шаблонів?

Відповіді:


158

Просто використовуйте спробу і зловити.

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__, як описано тут .


Дякую, я не міг зрозуміти, чому "з імпорту MySQLdb IntegrityError" не робить трюку. Здавалося, стек викликів показує, що саме бібліотека спричиняла помилку, але вона якось переміщується до django.db. Грр.
Джуліан

3
Як зазначено в документах v1.6 , e.__cause__переважно, згідно з PEP 3134 .
Jill-Jênn Vie

1
Якщо повідомлення не надійшло, спробуйте це: e.args
Джей Моді

e.message у мене не спрацював, але e.args [1] зробив роботу
Едгар Навасардян

@blissini - я змінив посилання, щоб вказати на документацію розробника
Тоні

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 / # процес-виняток для отримання додаткової інформації).

Зараз на вашому місці я б не припускав такого поняття, як "існує лише один очевидний випадок, коли може виникнути" IntegrityError "", тому я настійно рекомендую вам реєструвати виняток (і надсилати сповіщення електронною поштою) у проміжне програмне забезпечення.


Поміщення його в проміжне програмне забезпечення призведе не лише до помилки в додатку, але й у всіх додатках проекту.
Кріс Весселінг,

@ChrisWesseling: Цілком погоджуюсь, саме тому я згадав, що "я б не припускав такого, як" існує лише один очевидний випадок, коли може виникнути "IntegrityError" ""
bruno desthuilliers

1
Зброя не стріляє людям у ногу, люди стріляють людям у ногу. :-)
Кріс Весселінг 02

Я б не назвав це найпростішим рішенням, але це корисна альтернатива, про яку слід знати. Дякую.
напівзахищений

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 / Osim

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

Дякую @Soren Я щойно відредагував свою відповідь


Це не говорить, як це зробити.
Sören
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.