[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
This commit is contained in:
Tim Graham 2013-08-01 14:09:47 -04:00
parent b3e54f4a01
commit 196cc875b2
3 changed files with 37 additions and 11 deletions

View File

@ -146,7 +146,7 @@ class BaseDatabaseCreation(object):
Returns any ALTER TABLE statements to add constraints after the fact. Returns any ALTER TABLE statements to add constraints after the fact.
""" """
opts = model._meta opts = model._meta
if not opts.managed or opts.proxy or opts.swapped: if not opts.managed or opts.swapped:
return [] return []
qn = self.connection.ops.quote_name qn = self.connection.ops.quote_name
final_output = [] final_output = []

View File

@ -68,11 +68,18 @@ class Reporter(models.Model):
return "%s %s" % (self.first_name, self.last_name) return "%s %s" % (self.first_name, self.last_name)
class ReporterProxy(Reporter):
class Meta:
proxy = True
@python_2_unicode_compatible @python_2_unicode_compatible
class Article(models.Model): class Article(models.Model):
headline = models.CharField(max_length=100) headline = models.CharField(max_length=100)
pub_date = models.DateField() pub_date = models.DateField()
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter)
reporter_proxy = models.ForeignKey(ReporterProxy, null=True,
related_name='reporter_proxy')
def __str__(self): def __str__(self):
return self.headline return self.headline

View File

@ -613,12 +613,19 @@ class FkConstraintsTests(TransactionTestCase):
Try to create a model instance that violates a FK constraint. If it Try to create a model instance that violates a FK constraint. If it
fails it should fail with IntegrityError. 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: try:
a.save() a1.save()
except IntegrityError: except IntegrityError:
return pass
self.skipTest("This backend does not support integrity checks.") 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): def test_integrity_checks_on_update(self):
""" """
@ -627,14 +634,26 @@ class FkConstraintsTests(TransactionTestCase):
""" """
# Create an Article. # Create an Article.
models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r)
# Retrive it from the DB # Retrieve it from the DB
a = models.Article.objects.get(headline="Test article") a1 = models.Article.objects.get(headline="Test article")
a.reporter_id = 30 a1.reporter_id = 30
try: try:
a.save() a1.save()
except IntegrityError: except IntegrityError:
return pass
self.skipTest("This backend does not support integrity checks.") 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): def test_disable_constraint_checks_manually(self):
""" """