Skip to content

Commit

Permalink
Fixed #29945 -- Moved contrib.postgres uninstallation logic to the ap…
Browse files Browse the repository at this point in the history
…p config.
  • Loading branch information
charettes authored and timgraham committed Nov 12, 2018
1 parent b1243a5 commit 2f120ac
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
21 changes: 21 additions & 0 deletions django/contrib/postgres/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,38 @@
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':
Expand Down
9 changes: 1 addition & 8 deletions tests/postgres_tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,12 @@
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")
Expand Down
13 changes: 13 additions & 0 deletions tests/postgres_tests/test_apps.py
Original file line number Diff line number Diff line change
@@ -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))

0 comments on commit 2f120ac

Please sign in to comment.