From 196cc875b26f266e8f8dfd5be9daa0b8f246b9cd Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 1 Aug 2013 14:09:47 -0400 Subject: [PATCH] [1.6.x] Fixed #17519 -- Fixed missing SQL constraints to proxy models. Thanks thibaultj for the report, jenh for the patch, and charettes for the tests. Backport of aa830009de from master --- django/db/backends/creation.py | 2 +- tests/backends/models.py | 7 ++++++ tests/backends/tests.py | 39 +++++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py index c9e5c83ade2..bae439b4196 100644 --- a/django/db/backends/creation.py +++ b/django/db/backends/creation.py @@ -146,7 +146,7 @@ class BaseDatabaseCreation(object): Returns any ALTER TABLE statements to add constraints after the fact. """ opts = model._meta - if not opts.managed or opts.proxy or opts.swapped: + if not opts.managed or opts.swapped: return [] qn = self.connection.ops.quote_name final_output = [] diff --git a/tests/backends/models.py b/tests/backends/models.py index 4f03ddeacce..1508af43540 100644 --- a/tests/backends/models.py +++ b/tests/backends/models.py @@ -68,11 +68,18 @@ class Reporter(models.Model): return "%s %s" % (self.first_name, self.last_name) +class ReporterProxy(Reporter): + class Meta: + proxy = True + + @python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() reporter = models.ForeignKey(Reporter) + reporter_proxy = models.ForeignKey(ReporterProxy, null=True, + related_name='reporter_proxy') def __str__(self): return self.headline diff --git a/tests/backends/tests.py b/tests/backends/tests.py index b196133a684..b018d2a2106 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -613,12 +613,19 @@ class FkConstraintsTests(TransactionTestCase): Try to create a model instance that violates a FK constraint. If it fails it should fail with IntegrityError. """ - a = models.Article(headline="This is a test", pub_date=datetime.datetime(2005, 7, 27), reporter_id=30) + a1 = models.Article(headline="This is a test", pub_date=datetime.datetime(2005, 7, 27), reporter_id=30) try: - a.save() + a1.save() except IntegrityError: - return - self.skipTest("This backend does not support integrity checks.") + pass + else: + self.skipTest("This backend does not support integrity checks.") + # Now that we know this backend supports integrity checks we make sure + # constraints are also enforced for proxy models. Refs #17519 + a2 = models.Article(headline='This is another test', reporter=self.r, + pub_date=datetime.datetime(2012, 8, 3), + reporter_proxy_id=30) + self.assertRaises(IntegrityError, a2.save) def test_integrity_checks_on_update(self): """ @@ -627,14 +634,26 @@ class FkConstraintsTests(TransactionTestCase): """ # Create an Article. models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) - # Retrive it from the DB - a = models.Article.objects.get(headline="Test article") - a.reporter_id = 30 + # Retrieve it from the DB + a1 = models.Article.objects.get(headline="Test article") + a1.reporter_id = 30 try: - a.save() + a1.save() except IntegrityError: - return - self.skipTest("This backend does not support integrity checks.") + pass + else: + self.skipTest("This backend does not support integrity checks.") + # Now that we know this backend supports integrity checks we make sure + # constraints are also enforced for proxy models. Refs #17519 + # Create another article + r_proxy = models.ReporterProxy.objects.get(pk=self.r.pk) + models.Article.objects.create(headline='Another article', + pub_date=datetime.datetime(1988, 5, 15), + reporter=self.r, reporter_proxy=r_proxy) + # Retreive the second article from the DB + a2 = models.Article.objects.get(headline='Another article') + a2.reporter_proxy_id = 30 + self.assertRaises(IntegrityError, a2.save) def test_disable_constraint_checks_manually(self): """