Fixed #25454 -- Ensured register_hstore_handler is called for all connections

Thanks Simon Charette for help with the patch.
This commit is contained in:
Claude Paroz 2016-07-20 10:18:11 +02:00
parent 7bf3ba0d0c
commit 283b468462
3 changed files with 24 additions and 8 deletions

View File

@ -1,4 +1,5 @@
from django.apps import AppConfig from django.apps import AppConfig
from django.db import connections
from django.db.backends.signals import connection_created from django.db.backends.signals import connection_created
from django.db.models import CharField, TextField from django.db.models import CharField, TextField
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -12,6 +13,10 @@ class PostgresConfig(AppConfig):
verbose_name = _('PostgreSQL extensions') verbose_name = _('PostgreSQL extensions')
def ready(self): 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) connection_created.connect(register_hstore_handler)
CharField.register_lookup(Unaccent) CharField.register_lookup(Unaccent)
TextField.register_lookup(Unaccent) TextField.register_lookup(Unaccent)

View File

@ -1,9 +1,16 @@
import unittest import unittest
from django.db import connection from django.db import connection
from django.db.backends.signals import connection_created
from django.test import TestCase from django.test import TestCase
@unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific tests") @unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific tests")
class PostgreSQLTestCase(TestCase): 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()

View File

@ -5,6 +5,7 @@ import json
from django.core import exceptions, serializers from django.core import exceptions, serializers
from django.forms import Form from django.forms import Form
from django.test.utils import modify_settings
from . import PostgreSQLTestCase from . import PostgreSQLTestCase
from .models import HStoreModel from .models import HStoreModel
@ -17,9 +18,12 @@ except ImportError:
pass pass
class SimpleTests(PostgreSQLTestCase): @modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'})
apps = ['django.contrib.postgres'] class HStoreTestCase(PostgreSQLTestCase):
pass
class SimpleTests(HStoreTestCase):
def test_save_load_success(self): def test_save_load_success(self):
value = {'a': 'b'} value = {'a': 'b'}
instance = HStoreModel(field=value) instance = HStoreModel(field=value)
@ -55,7 +59,7 @@ class SimpleTests(PostgreSQLTestCase):
self.assertDictEqual(instance.field, expected_value) self.assertDictEqual(instance.field, expected_value)
class TestQuerying(PostgreSQLTestCase): class TestQuerying(HStoreTestCase):
def setUp(self): def setUp(self):
self.objs = [ self.objs = [
@ -164,7 +168,7 @@ class TestQuerying(PostgreSQLTestCase):
) )
class TestSerialization(PostgreSQLTestCase): class TestSerialization(HStoreTestCase):
test_data = ('[{"fields": {"field": "{\\"a\\": \\"b\\"}"}, ' test_data = ('[{"fields": {"field": "{\\"a\\": \\"b\\"}"}, '
'"model": "postgres_tests.hstoremodel", "pk": null}]') '"model": "postgres_tests.hstoremodel", "pk": null}]')
@ -184,7 +188,7 @@ class TestSerialization(PostgreSQLTestCase):
self.assertEqual(instance.field, new_instance.field) self.assertEqual(instance.field, new_instance.field)
class TestValidation(PostgreSQLTestCase): class TestValidation(HStoreTestCase):
def test_not_a_string(self): def test_not_a_string(self):
field = HStoreField() 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.') 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): def test_valid(self):
field = forms.HStoreField() field = forms.HStoreField()
@ -252,7 +256,7 @@ class TestFormField(PostgreSQLTestCase):
self.assertTrue(form_w_hstore.has_changed()) self.assertTrue(form_w_hstore.has_changed())
class TestValidator(PostgreSQLTestCase): class TestValidator(HStoreTestCase):
def test_simple_valid(self): def test_simple_valid(self):
validator = KeysValidator(keys=['a', 'b']) validator = KeysValidator(keys=['a', 'b'])