summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charettes@users.noreply.github.com>2018-11-12 11:15:48 -0500
committerTim Graham <timograham@gmail.com>2018-11-12 11:15:48 -0500
commit2f120ac51722a257219a7577759702605cefddf4 (patch)
tree05b9c93c70fcbe9b795af67ca59e2dac44ce4626
parentb1243a55a5916ed08a726b011bc05d40f717ef40 (diff)
Fixed #29945 -- Moved contrib.postgres uninstallation logic to the app config.
-rw-r--r--django/contrib/postgres/apps.py21
-rw-r--r--tests/postgres_tests/__init__.py9
-rw-r--r--tests/postgres_tests/test_apps.py13
3 files changed, 35 insertions, 8 deletions
diff --git a/django/contrib/postgres/apps.py b/django/contrib/postgres/apps.py
index f1ec09806a..9f29d72f49 100644
--- a/django/contrib/postgres/apps.py
+++ b/django/contrib/postgres/apps.py
@@ -2,17 +2,38 @@ from django.apps import AppConfig
from django.db import connections
from django.db.backends.signals import connection_created
from django.db.models import CharField, TextField
+from django.test.signals import setting_changed
from django.utils.translation import gettext_lazy as _
from .lookups import SearchLookup, TrigramSimilar, Unaccent
from .signals import register_type_handlers
+def uninstall_if_needed(setting, value, enter, **kwargs):
+ """
+ Undo the effects of PostgresConfig.ready() when django.contrib.postgres
+ is "uninstalled" by override_settings().
+ """
+ if not enter and setting == 'INSTALLED_APPS' and 'django.contrib.postgres' not in set(value):
+ connection_created.disconnect(register_type_handlers)
+ CharField._unregister_lookup(Unaccent)
+ TextField._unregister_lookup(Unaccent)
+ CharField._unregister_lookup(SearchLookup)
+ TextField._unregister_lookup(SearchLookup)
+ CharField._unregister_lookup(TrigramSimilar)
+ TextField._unregister_lookup(TrigramSimilar)
+ # Disconnect this receiver until the next time this app is installed
+ # and ready() connects it again to prevent unnecessary processing on
+ # each setting change.
+ setting_changed.disconnect(uninstall_if_needed)
+
+
class PostgresConfig(AppConfig):
name = 'django.contrib.postgres'
verbose_name = _('PostgreSQL extensions')
def ready(self):
+ setting_changed.connect(uninstall_if_needed)
# Connections may already exist before we are called.
for conn in connections.all():
if conn.vendor == 'postgresql':
diff --git a/tests/postgres_tests/__init__.py b/tests/postgres_tests/__init__.py
index 24d78c9bfe..d2e5d3bea4 100644
--- a/tests/postgres_tests/__init__.py
+++ b/tests/postgres_tests/__init__.py
@@ -3,19 +3,12 @@ import unittest
from forms_tests.widget_tests.base import WidgetTest
from django.db import connection
-from django.db.backends.signals import connection_created
from django.test import TestCase, modify_settings
@unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific tests")
class PostgreSQLTestCase(TestCase):
- @classmethod
- def tearDownClass(cls):
- # No need to keep that signal overhead for non PostgreSQL-related tests.
- from django.contrib.postgres.signals import register_type_handlers
-
- connection_created.disconnect(register_type_handlers)
- super().tearDownClass()
+ pass
@unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific tests")
diff --git a/tests/postgres_tests/test_apps.py b/tests/postgres_tests/test_apps.py
new file mode 100644
index 0000000000..a5740f9d15
--- /dev/null
+++ b/tests/postgres_tests/test_apps.py
@@ -0,0 +1,13 @@
+from django.db.backends.signals import connection_created
+from django.test.utils import modify_settings
+
+from . import PostgreSQLTestCase
+
+
+class PostgresConfigTests(PostgreSQLTestCase):
+ def test_register_type_handlers_connection(self):
+ from django.contrib.postgres.signals import register_type_handlers
+ self.assertNotIn(register_type_handlers, connection_created._live_receivers(None))
+ with modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'}):
+ self.assertIn(register_type_handlers, connection_created._live_receivers(None))
+ self.assertNotIn(register_type_handlers, connection_created._live_receivers(None))