diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
a
|
b
|
|
255 | 255 | def make_debug_cursor(self, cursor): |
256 | 256 | return util.CursorDebugWrapper(cursor, self) |
257 | 257 | |
| 258 | def check_constraints(self): |
| 259 | sql = self.ops.check_constraints_sql() |
| 260 | for s in sql: |
| 261 | self.cursor().execute(s) |
| 262 | |
258 | 263 | class BaseDatabaseFeatures(object): |
259 | 264 | allows_group_by_pk = False |
260 | 265 | # True if django.db.backend.utils.typecast_timestamp is used on values |
… |
… |
|
440 | 445 | """ |
441 | 446 | return '' |
442 | 447 | |
| 448 | def check_constraints_sql(self): |
| 449 | """ |
| 450 | Returns the SQL necessary to force deferred constraints to be checked. |
| 451 | """ |
| 452 | return [] |
| 453 | |
443 | 454 | def drop_foreignkey_sql(self): |
444 | 455 | """ |
445 | 456 | Returns the SQL command that drops a foreign key. |
diff --git a/django/db/backends/postgresql_psycopg2/operations.py b/django/db/backends/postgresql_psycopg2/operations.py
a
|
b
|
|
48 | 48 | def deferrable_sql(self): |
49 | 49 | return " DEFERRABLE INITIALLY DEFERRED" |
50 | 50 | |
| 51 | def check_constraints_sql(self): |
| 52 | return ["SET CONSTRAINTS ALL IMMEDIATE"] |
| 53 | |
51 | 54 | def lookup_cast(self, lookup_type): |
52 | 55 | lookup = '%s' |
53 | 56 | |
diff --git a/django/test/testcases.py b/django/test/testcases.py
a
|
b
|
|
304 | 304 | def _post_teardown(self): |
305 | 305 | """ Performs any post-test things. This includes: |
306 | 306 | |
| 307 | * Tearing down database fixtures, if any. |
307 | 308 | * Putting back the original ROOT_URLCONF if it was changed. |
308 | 309 | * Force closing the connection, so that the next test gets |
309 | 310 | a clean cursor. |
… |
… |
|
597 | 598 | |
598 | 599 | restore_transaction_methods() |
599 | 600 | for db in databases: |
600 | | transaction.rollback(using=db) |
601 | | transaction.leave_transaction_management(using=db) |
| 601 | # Force constraints check execution (on backends that support |
| 602 | # deferring them) before rolling back the transaction. |
| 603 | try: |
| 604 | connections[db].check_constraints() |
| 605 | finally: |
| 606 | transaction.rollback(using=db) |
| 607 | transaction.leave_transaction_management(using=db) |
602 | 608 | |
603 | 609 | def _deferredSkip(condition, reason): |
604 | 610 | def decorator(test_func): |