Commit 31b1cbc6 authored by Julien Phalip's avatar Julien Phalip
Browse files

Fixed #16340 -- Made `get_or_create()` re-raise any `IntegrityError` with its...

Fixed #16340 -- Made `get_or_create()` re-raise any `IntegrityError` with its original traceback. Thanks to d0ugal and Jonas Obrist.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17333 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent fc9e0606
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ The main QuerySet implementation. This provides the public API for the ORM.

import copy
import itertools
import sys

from django.db import connections, router, transaction, IntegrityError
from django.db.models.fields import AutoField
@@ -450,10 +451,12 @@ class QuerySet(object):
                return obj, True
            except IntegrityError, e:
                transaction.savepoint_rollback(sid, using=self.db)
                exc_info = sys.exc_info()
                try:
                    return self.get(**lookup), False
                except self.model.DoesNotExist:
                    raise e
                    # Re-raise the IntegrityError with its original traceback.
                    raise exc_info[1], None, exc_info[2]

    def latest(self, field_name=None):
        """
+12 −0
Original line number Diff line number Diff line
from __future__ import absolute_import

from datetime import date
import traceback

from django.db import IntegrityError
from django.test import TestCase
@@ -52,3 +53,14 @@ class GetOrCreateTests(TestCase):
            ManualPrimaryKeyTest.objects.get_or_create, id=1, data="Different"
        )
        self.assertEqual(ManualPrimaryKeyTest.objects.get(id=1).data, "Original")

        # get_or_create should raise IntegrityErrors with the full traceback.
        # This is tested by checking that a known method call is in the traceback.
        # We cannot use assertRaises/assertRaises here because we need to inspect
        # the actual traceback. Refs #16340.
        try:
            ManualPrimaryKeyTest.objects.get_or_create(id=1, data="Different")
        except IntegrityError, e:
            formatted_traceback = traceback.format_exc()
            self.assertIn('obj.save', formatted_traceback)