From 283b468462a586fd9bf7a2794e9b9a20a7e8a2d9 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Wed, 20 Jul 2016 10:18:11 +0200 Subject: [PATCH] Fixed #25454 -- Ensured register_hstore_handler is called for all connections Thanks Simon Charette for help with the patch. --- django/contrib/postgres/apps.py | 5 +++++ tests/postgres_tests/__init__.py | 9 ++++++++- tests/postgres_tests/test_hstore.py | 18 +++++++++++------- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/django/contrib/postgres/apps.py b/django/contrib/postgres/apps.py index e7f76b2017..0eeee6332b 100644 --- a/django/contrib/postgres/apps.py +++ b/django/contrib/postgres/apps.py @@ -1,4 +1,5 @@ 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.utils.translation import ugettext_lazy as _ @@ -12,6 +13,10 @@ class PostgresConfig(AppConfig): verbose_name = _('PostgreSQL extensions') def ready(self): + # Connections may already exist before we are called. + for conn in connections.all(): + if conn.connection is not None: + register_hstore_handler(conn) connection_created.connect(register_hstore_handler) CharField.register_lookup(Unaccent) TextField.register_lookup(Unaccent) diff --git a/tests/postgres_tests/__init__.py b/tests/postgres_tests/__init__.py index 55b88427ef..dbb913dbba 100644 --- a/tests/postgres_tests/__init__.py +++ b/tests/postgres_tests/__init__.py @@ -1,9 +1,16 @@ import unittest from django.db import connection +from django.db.backends.signals import connection_created from django.test import TestCase @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific tests") class PostgreSQLTestCase(TestCase): - pass + @classmethod + def tearDownClass(cls): + # No need to keep that signal overhead for non PostgreSQL-related tests. + from django.contrib.postgres.signals import register_hstore_handler + + connection_created.disconnect(register_hstore_handler) + super(PostgreSQLTestCase, cls).tearDownClass() diff --git a/tests/postgres_tests/test_hstore.py b/tests/postgres_tests/test_hstore.py index 0afa630e46..fef71f1ef4 100644 --- a/tests/postgres_tests/test_hstore.py +++ b/tests/postgres_tests/test_hstore.py @@ -5,6 +5,7 @@ import json from django.core import exceptions, serializers from django.forms import Form +from django.test.utils import modify_settings from . import PostgreSQLTestCase from .models import HStoreModel @@ -17,9 +18,12 @@ except ImportError: pass -class SimpleTests(PostgreSQLTestCase): - apps = ['django.contrib.postgres'] +@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'}) +class HStoreTestCase(PostgreSQLTestCase): + pass + +class SimpleTests(HStoreTestCase): def test_save_load_success(self): value = {'a': 'b'} instance = HStoreModel(field=value) @@ -55,7 +59,7 @@ class SimpleTests(PostgreSQLTestCase): self.assertDictEqual(instance.field, expected_value) -class TestQuerying(PostgreSQLTestCase): +class TestQuerying(HStoreTestCase): def setUp(self): self.objs = [ @@ -164,7 +168,7 @@ class TestQuerying(PostgreSQLTestCase): ) -class TestSerialization(PostgreSQLTestCase): +class TestSerialization(HStoreTestCase): test_data = ('[{"fields": {"field": "{\\"a\\": \\"b\\"}"}, ' '"model": "postgres_tests.hstoremodel", "pk": null}]') @@ -184,7 +188,7 @@ class TestSerialization(PostgreSQLTestCase): self.assertEqual(instance.field, new_instance.field) -class TestValidation(PostgreSQLTestCase): +class TestValidation(HStoreTestCase): def test_not_a_string(self): field = HStoreField() @@ -194,7 +198,7 @@ class TestValidation(PostgreSQLTestCase): self.assertEqual(cm.exception.message % cm.exception.params, 'The value of "a" is not a string.') -class TestFormField(PostgreSQLTestCase): +class TestFormField(HStoreTestCase): def test_valid(self): field = forms.HStoreField() @@ -252,7 +256,7 @@ class TestFormField(PostgreSQLTestCase): self.assertTrue(form_w_hstore.has_changed()) -class TestValidator(PostgreSQLTestCase): +class TestValidator(HStoreTestCase): def test_simple_valid(self): validator = KeysValidator(keys=['a', 'b'])