diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 6f1f4b9..f9527be 100644
a
|
b
|
class BaseDatabaseFeatures(object):
|
405 | 405 | supports_transactions = None |
406 | 406 | supports_stddev = None |
407 | 407 | can_introspect_foreign_keys = None |
| 408 | supports_foreign_keys = None |
408 | 409 | |
409 | 410 | # Support for the DISTINCT ON clause |
410 | 411 | can_distinct_on_fields = False |
… |
… |
class BaseDatabaseFeatures(object):
|
418 | 419 | self.supports_transactions = self._supports_transactions() |
419 | 420 | self.supports_stddev = self._supports_stddev() |
420 | 421 | self.can_introspect_foreign_keys = self._can_introspect_foreign_keys() |
| 422 | self.supports_foreign_keys = self._supports_foreign_keys() |
421 | 423 | |
422 | 424 | def _supports_transactions(self): |
423 | 425 | "Confirm support for transactions" |
… |
… |
class BaseDatabaseFeatures(object):
|
448 | 450 | # which can't do it for MyISAM tables |
449 | 451 | return True |
450 | 452 | |
| 453 | def _supports_foreign_keys(self): |
| 454 | """ |
| 455 | Check support for foreign keys. |
| 456 | """ |
| 457 | return True |
| 458 | |
451 | 459 | |
452 | 460 | class BaseDatabaseOperations(object): |
453 | 461 | """ |
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index faaefca..e37fc02 100644
a
|
b
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
187 | 187 | "Confirm support for introspected foreign keys" |
188 | 188 | return self._mysql_storage_engine() != 'MyISAM' |
189 | 189 | |
| 190 | def _supports_foreign_keys(self): |
| 191 | "MyISAM does not support foreign keys." |
| 192 | return self._mysql_storage_engine() != 'MyISAM' |
| 193 | |
| 194 | |
190 | 195 | class DatabaseOperations(BaseDatabaseOperations): |
191 | 196 | compiler_module = "django.db.backends.mysql.compiler" |
192 | 197 | |
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 0b19442..57bb567 100644
a
|
b
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
103 | 103 | cursor.execute('DROP TABLE STDDEV_TEST') |
104 | 104 | return has_support |
105 | 105 | |
| 106 | def _supports_foreign_keys(self): |
| 107 | """ |
| 108 | Standard SQLite does not support foreign key constraints. However, |
| 109 | one can compile an edition which does. Currently we just return false, |
| 110 | but we could check if a foreign key constraint is enforced by sqlite |
| 111 | here. |
| 112 | """ |
| 113 | return False |
| 114 | |
106 | 115 | class DatabaseOperations(BaseDatabaseOperations): |
107 | 116 | def date_extract_sql(self, lookup_type, field_name): |
108 | 117 | # sqlite doesn't support extract, so we fake it with the user-defined |
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py
index d5b1ea8..cffc4ab 100644
a
|
b
|
class BackendTestCase(TestCase):
|
379 | 379 | with self.assertRaises(DatabaseError): |
380 | 380 | cursor.execute(query) |
381 | 381 | |
382 | | # We don't make these tests conditional because that means we would need to |
383 | | # check and differentiate between: |
384 | | # * MySQL+InnoDB, MySQL+MYISAM (something we currently can't do). |
385 | | # * if sqlite3 (if/once we get #14204 fixed) has referential integrity turned |
386 | | # on or not, something that would be controlled by runtime support and user |
387 | | # preference. |
388 | | # verify if its type is django.database.db.IntegrityError. |
389 | 382 | |
390 | 383 | class FkConstraintsTests(TransactionTestCase): |
391 | 384 | |
… |
… |
class FkConstraintsTests(TransactionTestCase):
|
393 | 386 | # Create a Reporter. |
394 | 387 | self.r = models.Reporter.objects.create(first_name='John', last_name='Smith') |
395 | 388 | |
| 389 | @skipUnlessDBFeature('supports_foreign_keys') |
396 | 390 | def test_integrity_checks_on_creation(self): |
397 | 391 | """ |
398 | 392 | Try to create a model instance that violates a FK constraint. If it |
399 | 393 | fails it should fail with IntegrityError. |
400 | 394 | """ |
401 | 395 | a = models.Article(headline="This is a test", pub_date=datetime.datetime(2005, 7, 27), reporter_id=30) |
402 | | try: |
| 396 | with self.assertRaises(IntegrityError): |
403 | 397 | a.save() |
404 | | except IntegrityError: |
405 | | return |
406 | | self.skipTest("This backend does not support integrity checks.") |
407 | 398 | |
| 399 | @skipUnlessDBFeature('supports_foreign_keys') |
408 | 400 | def test_integrity_checks_on_update(self): |
409 | 401 | """ |
410 | 402 | Try to update a model instance introducing a FK constraint violation. |
… |
… |
class FkConstraintsTests(TransactionTestCase):
|
415 | 407 | # Retrive it from the DB |
416 | 408 | a = models.Article.objects.get(headline="Test article") |
417 | 409 | a.reporter_id = 30 |
418 | | try: |
| 410 | with self.assertRaises(IntegrityError): |
419 | 411 | a.save() |
420 | | except IntegrityError: |
421 | | return |
422 | | self.skipTest("This backend does not support integrity checks.") |
423 | 412 | |
424 | 413 | def test_disable_constraint_checks_manually(self): |
425 | 414 | """ |