Fixed #17519 -- Fixed missing SQL constraints to proxy models.

Thanks thibaultj for the report, jenh for the patch,
and charettes for the tests.
This commit is contained in:
Tim Graham 2013-08-01 14:09:47 -04:00
parent 31ee120787
commit aa830009de
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

@ -614,12 +614,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):
""" """
@ -628,14 +635,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):
""" """