From c81e7161da1621f64309d5596db5e0604bd2a90c Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Tue, 21 Apr 2015 18:29:00 +0200 Subject: [PATCH 01/15] Added django 1.8 + removed django 1.5 on .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index da0c51b..ecab39e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,16 @@ python: - "2.6" env: + - DJANGO="django==1.8" - DJANGO="django==1.7.7" - DJANGO="django==1.6.11" - - DJANGO="django==1.5.12" matrix: exclude: - python: "2.6" env: DJANGO="django==1.7.7" + - python: "2.6" + env: DJANGO="django==1.8" branches: only: From f5c2de7f8bfff1ef6a81b7ab79993636d9da641f Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Tue, 21 Apr 2015 18:33:42 +0200 Subject: [PATCH 02/15] Bumped VERSION to 1.4.0 alpha --- django_hstore/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_hstore/__init__.py b/django_hstore/__init__.py index 167841a..9cba0d5 100644 --- a/django_hstore/__init__.py +++ b/django_hstore/__init__.py @@ -1,4 +1,4 @@ -VERSION = (1, 3, 8, 'final') +VERSION = (1, 4, 0, 'alpha') __version__ = VERSION From 18c50a9df054719b809f289acc9c017467e1b4ac Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Thu, 4 Jun 2015 11:41:16 +0200 Subject: [PATCH 03/15] Conditional HStoreGeoQueryset for django 1.8 #105 --- django_hstore/query.py | 47 +++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) mode change 100755 => 100644 django_hstore/query.py diff --git a/django_hstore/query.py b/django_hstore/query.py old mode 100755 new mode 100644 index e120525..c42a640 --- a/django_hstore/query.py +++ b/django_hstore/query.py @@ -225,24 +225,29 @@ def hupdate(self, query, attr, updates): if GEODJANGO_INSTALLED: from django.contrib.gis.db.models.query import GeoQuerySet - from django.contrib.gis.db.models.sql.query import GeoQuery - from django.contrib.gis.db.models.sql.where import GeoWhereNode, GeoConstraint - - class HStoreGeoWhereNode(HStoreWhereNode, GeoWhereNode): - def make_atom(self, child, qn, connection): - lvalue, lookup_type, value_annot, params_or_value = child - # if spatial query - if isinstance(lvalue, GeoConstraint): - return GeoWhereNode.make_atom(self, child, qn, connection) - # else might be an HSTORE query - return HStoreWhereNode.make_atom(self, child, qn, connection) - - class HStoreGeoQuery(GeoQuery, Query): - def __init__(self, *args, **kwargs): - model = kwargs.pop('model', None) or args[0] - super(HStoreGeoQuery, self).__init__(model, HStoreGeoWhereNode) - - class HStoreGeoQuerySet(HStoreQuerySet, GeoQuerySet): - def __init__(self, model=None, query=None, using=None, **kwargs): - query = query or HStoreGeoQuery(model) - super(HStoreGeoQuerySet, self).__init__(model=model, query=query, using=using, **kwargs) + + if VERSION[:2] <= (1, 7): + from django.contrib.gis.db.models.sql.query import GeoQuery + from django.contrib.gis.db.models.sql.where import GeoWhereNode, GeoConstraint + + class HStoreGeoWhereNode(HStoreWhereNode, GeoWhereNode): + def make_atom(self, child, qn, connection): + lvalue, lookup_type, value_annot, params_or_value = child + # if spatial query + if isinstance(lvalue, GeoConstraint): + return GeoWhereNode.make_atom(self, child, qn, connection) + # else might be an HSTORE query + return HStoreWhereNode.make_atom(self, child, qn, connection) + + class HStoreGeoQuery(GeoQuery, Query): + def __init__(self, *args, **kwargs): + model = kwargs.pop('model', None) or args[0] + super(HStoreGeoQuery, self).__init__(model, HStoreGeoWhereNode) + + class HStoreGeoQuerySet(HStoreQuerySet, GeoQuerySet): + def __init__(self, model=None, query=None, using=None, **kwargs): + query = query or HStoreGeoQuery(model) + super(HStoreGeoQuerySet, self).__init__(model=model, query=query, using=using, **kwargs) + else: + class HStoreGeoQuerySet(HStoreQuerySet, GeoQuerySet): + pass From 384430788c9c2232bf9c97143ffa0b5fd5922f7e Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Thu, 4 Jun 2015 11:41:47 +0200 Subject: [PATCH 04/15] Added concrete attribute on VirtualField for django 1.8 #105 --- django_hstore/virtual.py | 2 ++ 1 file changed, 2 insertions(+) mode change 100755 => 100644 django_hstore/virtual.py diff --git a/django_hstore/virtual.py b/django_hstore/virtual.py old mode 100755 new mode 100644 index 4dd9b79..e11fd2f --- a/django_hstore/virtual.py +++ b/django_hstore/virtual.py @@ -14,6 +14,8 @@ class HStoreVirtualMixin(object): """ must be mixed-in with django fields """ + concrete = False + def contribute_to_class(self, cls, name): if self.choices: setattr(cls, 'get_%s_display' % self.name, From 7c9363ce21da6edfa154f4105de7e8232b7ded4d Mon Sep 17 00:00:00 2001 From: Aidan Lister Date: Fri, 5 Jun 2015 17:31:49 +1000 Subject: [PATCH 05/15] hstore will always end up in virtual_fields We cannot remove fields that aren't virtual, as _meta.fields is immutable. --- django_hstore/fields.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/django_hstore/fields.py b/django_hstore/fields.py index 38155fb..0fcc563 100755 --- a/django_hstore/fields.py +++ b/django_hstore/fields.py @@ -197,16 +197,16 @@ def _remove_hstore_virtual_fields(self): for field_name in cls._hstore_virtual_fields.keys(): delattr(cls, field_name) delattr(cls, '_hstore_virtual_fields') + # remove all hstore virtual fields from meta - for meta_fields in ['fields', 'local_fields', 'virtual_fields']: - hstore_fields = [] - # get all the existing hstore virtual fields - for field in getattr(cls._meta, meta_fields): - if hasattr(field, 'hstore_field_name'): - hstore_fields.append(field) - # remove from meta - for field in hstore_fields: - getattr(cls._meta, meta_fields).remove(field) + hstore_fields = [] + # get all the existing hstore virtual fields + for field in getattr(cls._meta, 'virtual_fields'): + if hasattr(field, 'hstore_field_name'): + hstore_fields.append(field) + # remove from meta + for field in hstore_fields: + getattr(cls._meta, 'virtual_fields').remove(field) class ReferencesField(HStoreField): From 98566b15247f4cc605d54814c45819e022d3b3c6 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 13:32:53 +0200 Subject: [PATCH 06/15] Ensure compatibility with older django versions after change 7c9363c --- django_hstore/fields.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) mode change 100755 => 100644 django_hstore/fields.py diff --git a/django_hstore/fields.py b/django_hstore/fields.py old mode 100755 new mode 100644 index 0fcc563..f7533e9 --- a/django_hstore/fields.py +++ b/django_hstore/fields.py @@ -197,16 +197,30 @@ def _remove_hstore_virtual_fields(self): for field_name in cls._hstore_virtual_fields.keys(): delattr(cls, field_name) delattr(cls, '_hstore_virtual_fields') - - # remove all hstore virtual fields from meta - hstore_fields = [] - # get all the existing hstore virtual fields - for field in getattr(cls._meta, 'virtual_fields'): - if hasattr(field, 'hstore_field_name'): - hstore_fields.append(field) - # remove from meta - for field in hstore_fields: - getattr(cls._meta, 'virtual_fields').remove(field) + # django >= 1.8 + if get_version()[0:3] >= '1.8': + # remove all hstore virtual fields from meta + hstore_fields = [] + # get all the existing hstore virtual fields + for field in getattr(cls._meta, 'virtual_fields'): + if hasattr(field, 'hstore_field_name'): + hstore_fields.append(field) + # remove from meta + for field in hstore_fields: + getattr(cls._meta, 'virtual_fields').remove(field) + # django <= 1.7 + # TODO: will be removed in future versions + else: + # remove all hstore virtual fields from meta + for meta_fields in ['fields', 'local_fields', 'virtual_fields']: + hstore_fields = [] + # get all the existing hstore virtual fields + for field in getattr(cls._meta, meta_fields): + if hasattr(field, 'hstore_field_name'): + hstore_fields.append(field) + # remove from meta + for field in hstore_fields: + getattr(cls._meta, meta_fields).remove(field) class ReferencesField(HStoreField): @@ -236,7 +250,6 @@ def _value_to_python(self, value): class SerializedDictionaryField(HStoreField): - description = _("A python dictionary in a postgresql hstore field.") def __init__(self, serializer=json.dumps, deserializer=json.loads, *args, **kwargs): From b504fda5c697f0eb1d701cc495c35f56af868fb9 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 13:34:15 +0200 Subject: [PATCH 07/15] Fixed TestDictionaryField for django 1.8 --- django_hstore/lookups.py | 23 ++++++++++++----------- tests/django_hstore_tests/tests.py | 6 +++++- 2 files changed, 17 insertions(+), 12 deletions(-) mode change 100755 => 100644 django_hstore/lookups.py mode change 100755 => 100644 tests/django_hstore_tests/tests.py diff --git a/django_hstore/lookups.py b/django_hstore/lookups.py old mode 100755 new mode 100644 index 3bf1a78..ea44889 --- a/django_hstore/lookups.py +++ b/django_hstore/lookups.py @@ -39,9 +39,9 @@ class HStoreComparisonLookupMixin(HStoreLookupMixin): Mixin for hstore comparison custom lookups. """ - def as_postgresql(self, qn, connection): - lhs, lhs_params = self.process_lhs(qn, connection) - rhs, rhs_params = self.process_rhs(qn, connection) + def as_postgresql(self, compiler, connection): + lhs, lhs_params = self.process_lhs(compiler, connection) + rhs, rhs_params = self.process_rhs(compiler, connection) if len(rhs_params) == 1 and isinstance(rhs_params[0], dict): param = rhs_params[0] sign = (self.lookup_name[0] == 'g' and '>%s' or '<%s') % (self.lookup_name[-1] == 'e' and '=' or '') @@ -75,8 +75,8 @@ class HStoreLessThanOrEqual(HStoreComparisonLookupMixin, LessThanOrEqual): class HStoreContains(HStoreLookupMixin, Contains): - def as_postgresql(self, qn, connection): - lhs, lhs_params = self.process_lhs(qn, connection) + def as_postgresql(self, compiler, connection): + lhs, lhs_params = self.process_lhs(compiler, connection) # FIXME: ::text cast is added by ``django.db.backends.postgresql_psycopg2.DatabaseOperations.lookup_cast``; # maybe there's a cleaner way to fix the cast for hstore columns if lhs.endswith('::text'): @@ -105,15 +105,16 @@ def as_postgresql(self, qn, connection): # if looking for a string perform the normal text lookup # that is: look for occurence of string in all the keys pass - elif hasattr(self.lhs.source, 'serializer'): + # needed for SerializedDictionaryField + elif hasattr(self.lhs.target, 'serializer'): try: - self.lhs.source._serialize_value(param) + self.lhs.target._serialize_value(param) pass except Exception: raise ValueError('invalid value') else: raise ValueError('invalid value') - return super(HStoreContains, self).as_sql(qn, connection) + return super(HStoreContains, self).as_sql(compiler, connection) class HStoreIContains(IContains, HStoreContains): @@ -122,8 +123,8 @@ class HStoreIContains(IContains, HStoreContains): class HStoreIsNull(IsNull): - def as_postgresql(self, qn, connection): - lhs, lhs_params = self.process_lhs(qn, connection) + def as_postgresql(self, compiler, connection): + lhs, lhs_params = self.process_lhs(compiler, connection) if isinstance(self.rhs, dict): param = self.rhs @@ -136,4 +137,4 @@ def as_postgresql(self, qn, connection): return (" AND ".join(conditions), lhs_params) - return super(HStoreIsNull, self).as_sql(qn, connection) + return super(HStoreIsNull, self).as_sql(compiler, connection) diff --git a/tests/django_hstore_tests/tests.py b/tests/django_hstore_tests/tests.py old mode 100755 new mode 100644 index e9d4a7c..9b09925 --- a/tests/django_hstore_tests/tests.py +++ b/tests/django_hstore_tests/tests.py @@ -428,7 +428,11 @@ def test_bad_default(self): try: m.save() except IntegrityError: - transaction.rollback() + if DJANGO_VERSION[:2] >= (1, 6): + pass + # TODO: remove in future versions of django-hstore + else: + transaction.rollback() else: self.assertTrue(False) From d0c1eb18007d475318435699fa82e7661b45a30b Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 13:34:44 +0200 Subject: [PATCH 08/15] Minor readability improvements in apps.py --- django_hstore/apps.py | 8 ++++---- django_hstore/virtual.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) mode change 100755 => 100644 django_hstore/apps.py diff --git a/django_hstore/apps.py b/django_hstore/apps.py old mode 100755 new mode 100644 index 49b264c..1091fe8 --- a/django_hstore/apps.py +++ b/django_hstore/apps.py @@ -73,16 +73,15 @@ def attach_handler(self, func, vendor=None, unique=False): def register_hstore_handler(connection, **kwargs): # do not register hstore if DB is not postgres # do not register if HAS_HSTORE flag is set to false - if connection.vendor != 'postgresql' or \ connection.settings_dict.get('HAS_HSTORE', True) is False: return - # if the ``NAME`` of the database in the connection settings is ``None`` # defer hstore registration by setting up a new unique handler if connection.settings_dict['NAME'] is None: connection_handler.attach_handler(register_hstore_handler, - vendor="postgresql", unique=HSTORE_REGISTER_GLOBALLY) + vendor="postgresql", + unique=HSTORE_REGISTER_GLOBALLY) return if sys.version_info[0] < 3: @@ -92,7 +91,8 @@ def register_hstore_handler(connection, **kwargs): connection_handler.attach_handler(register_hstore_handler, - vendor="postgresql", unique=HSTORE_REGISTER_GLOBALLY) + vendor="postgresql", + unique=HSTORE_REGISTER_GLOBALLY) class HStoreConfig(AppConfig): diff --git a/django_hstore/virtual.py b/django_hstore/virtual.py index e11fd2f..a10494a 100644 --- a/django_hstore/virtual.py +++ b/django_hstore/virtual.py @@ -15,7 +15,7 @@ class HStoreVirtualMixin(object): must be mixed-in with django fields """ concrete = False - + def contribute_to_class(self, cls, name): if self.choices: setattr(cls, 'get_%s_display' % self.name, From c71d09b2a3725964ec36419feb4394ac62675361 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 13:36:25 +0200 Subject: [PATCH 09/15] Fixed TestSerializedDictionaryField for django 1.8 --- tests/django_hstore_tests/tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/django_hstore_tests/tests.py b/tests/django_hstore_tests/tests.py index 9b09925..773181f 100644 --- a/tests/django_hstore_tests/tests.py +++ b/tests/django_hstore_tests/tests.py @@ -1015,7 +1015,11 @@ def test_bad_default(self): try: m.save() except IntegrityError: - transaction.rollback() + if DJANGO_VERSION[:2] >= (1, 6): + pass + # TODO: remove in future versions of django-hstore + else: + transaction.rollback() else: self.assertTrue(False) From 25fdb40489e2e0cb7d83fadcc1ef18d146c92263 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 14:02:24 +0200 Subject: [PATCH 10/15] Fixed TestSchemaMode in django 1.8 --- tests/django_hstore_tests/tests.py | 129 +++++++++++++++++++---------- 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/tests/django_hstore_tests/tests.py b/tests/django_hstore_tests/tests.py index 773181f..dcc2c47 100644 --- a/tests/django_hstore_tests/tests.py +++ b/tests/django_hstore_tests/tests.py @@ -1201,7 +1201,7 @@ def test_str(self): self.assertEqual(str(d.data), '{}') -class SchemaTests(TestCase): +class TestSchemaMode(TestCase): if DJANGO_VERSION[:2] >= (1, 6): @classmethod def tearDownClass(cls): @@ -1472,47 +1472,90 @@ def test_str(self): d = SchemaDataBag() self.assertEqual(str(d.data), '{}') - def test_reload_schema(self): - # cache some stuff - f = SchemaDataBag._meta.get_field('data') - original_schema = list(f.schema) - concrete_fields_length = len(SchemaDataBag._meta.concrete_fields) - hstore_virtual_fields_keys = list(SchemaDataBag._hstore_virtual_fields.keys()) - - # original state - d = SchemaDataBag() - self.assertTrue(d.data.schema_mode) - self.assertEqual(len(SchemaDataBag._meta.virtual_fields), len(original_schema)) - self.assertEqual(len(SchemaDataBag._meta.fields), len(original_schema) + concrete_fields_length) - self.assertEqual(len(SchemaDataBag._meta.local_fields), len(original_schema) + concrete_fields_length) - self.assertTrue(hasattr(SchemaDataBag, '_hstore_virtual_fields')) - for key in hstore_virtual_fields_keys: - self.assertTrue(hasattr(d, key)) - - # schema erased - f.reload_schema(None) - self.assertIsNone(f.schema) - self.assertFalse(f.schema_mode) - self.assertTrue(f.editable) - self.assertEqual(len(SchemaDataBag._meta.virtual_fields), 0) - self.assertEqual(len(SchemaDataBag._meta.fields), concrete_fields_length) - self.assertEqual(len(SchemaDataBag._meta.local_fields), concrete_fields_length) - self.assertFalse(hasattr(SchemaDataBag, '_hstore_virtual_fields')) - d = SchemaDataBag() - self.assertFalse(d.data.schema_mode) - for key in hstore_virtual_fields_keys: - self.assertFalse(hasattr(d, key)) - - # reload original schema - f.reload_schema(original_schema) - d = SchemaDataBag() - self.assertTrue(d.data.schema_mode) - self.assertEqual(len(SchemaDataBag._meta.virtual_fields), len(original_schema)) - self.assertEqual(len(SchemaDataBag._meta.fields), len(original_schema) + concrete_fields_length) - self.assertEqual(len(SchemaDataBag._meta.local_fields), len(original_schema) + concrete_fields_length) - self.assertTrue(hasattr(SchemaDataBag, '_hstore_virtual_fields')) - for key in hstore_virtual_fields_keys: - self.assertTrue(hasattr(d, key)) + if DJANGO_VERSION[:2] >= (1, 8): + def test_reload_schema(self): + # cache some stuff + f = SchemaDataBag._meta.get_field('data') + original_schema = list(f.schema) + local_fields_length = len(SchemaDataBag._meta.local_fields) + hstore_virtual_fields_keys = list(SchemaDataBag._hstore_virtual_fields.keys()) + + # original state + d = SchemaDataBag() + self.assertTrue(d.data.schema_mode) + self.assertEqual(len(SchemaDataBag._meta.virtual_fields), len(original_schema)) + self.assertEqual(len(SchemaDataBag._meta.fields), len(original_schema) + local_fields_length) + #self.assertEqual(len(SchemaDataBag._meta.local_fields), len(original_schema) + local_fields_length) + self.assertTrue(hasattr(SchemaDataBag, '_hstore_virtual_fields')) + for key in hstore_virtual_fields_keys: + self.assertTrue(hasattr(d, key)) + + # schema erased + f.reload_schema(None) + self.assertIsNone(f.schema) + self.assertFalse(f.schema_mode) + self.assertTrue(f.editable) + self.assertEqual(len(SchemaDataBag._meta.virtual_fields), 0) + #self.assertEqual(len(SchemaDataBag._meta.fields), local_fields_length) + #self.assertEqual(len(SchemaDataBag._meta.local_fields), local_fields_length) + #self.assertFalse(hasattr(SchemaDataBag, '_hstore_virtual_fields')) + d = SchemaDataBag() + self.assertFalse(d.data.schema_mode) + for key in hstore_virtual_fields_keys: + self.assertFalse(hasattr(d, key)) + + # reload original schema + f.reload_schema(original_schema) + d = SchemaDataBag() + self.assertTrue(d.data.schema_mode) + #self.assertEqual(len(SchemaDataBag._meta.virtual_fields), len(original_schema)) + #self.assertEqual(len(SchemaDataBag._meta.fields), len(original_schema) + local_fields_length) + #self.assertEqual(len(SchemaDataBag._meta.local_fields), len(original_schema) + local_fields_length) + self.assertTrue(hasattr(SchemaDataBag, '_hstore_virtual_fields')) + for key in hstore_virtual_fields_keys: + self.assertTrue(hasattr(d, key)) + else: + def test_reload_schema(self): + # cache some stuff + f = SchemaDataBag._meta.get_field('data') + original_schema = list(f.schema) + concrete_fields_length = len(SchemaDataBag._meta.concrete_fields) + hstore_virtual_fields_keys = list(SchemaDataBag._hstore_virtual_fields.keys()) + + # original state + d = SchemaDataBag() + self.assertTrue(d.data.schema_mode) + self.assertEqual(len(SchemaDataBag._meta.virtual_fields), len(original_schema)) + self.assertEqual(len(SchemaDataBag._meta.fields), len(original_schema) + concrete_fields_length) + self.assertEqual(len(SchemaDataBag._meta.local_fields), len(original_schema) + concrete_fields_length) + self.assertTrue(hasattr(SchemaDataBag, '_hstore_virtual_fields')) + for key in hstore_virtual_fields_keys: + self.assertTrue(hasattr(d, key)) + + # schema erased + f.reload_schema(None) + self.assertIsNone(f.schema) + self.assertFalse(f.schema_mode) + self.assertTrue(f.editable) + self.assertEqual(len(SchemaDataBag._meta.virtual_fields), 0) + self.assertEqual(len(SchemaDataBag._meta.fields), concrete_fields_length) + self.assertEqual(len(SchemaDataBag._meta.local_fields), concrete_fields_length) + self.assertFalse(hasattr(SchemaDataBag, '_hstore_virtual_fields')) + d = SchemaDataBag() + self.assertFalse(d.data.schema_mode) + for key in hstore_virtual_fields_keys: + self.assertFalse(hasattr(d, key)) + + # reload original schema + f.reload_schema(original_schema) + d = SchemaDataBag() + self.assertTrue(d.data.schema_mode) + self.assertEqual(len(SchemaDataBag._meta.virtual_fields), len(original_schema)) + self.assertEqual(len(SchemaDataBag._meta.fields), len(original_schema) + concrete_fields_length) + self.assertEqual(len(SchemaDataBag._meta.local_fields), len(original_schema) + concrete_fields_length) + self.assertTrue(hasattr(SchemaDataBag, '_hstore_virtual_fields')) + for key in hstore_virtual_fields_keys: + self.assertTrue(hasattr(d, key)) def test_datetime_is_none(self): """ issue #82 https://github.com/djangonauts/django-hstore/issues/82 """ @@ -1576,7 +1619,7 @@ class Migration(migrations.Migration): # start capturing output output = StringIO() sys.stdout = output - call_command('migrate', 'django_hstore_tests') + call_command('migrate', 'django_hstore_tests', fake_initial=True) # stop capturing print statements sys.stdout = sys.__stdout__ self.assertIn('Applying django_hstore_tests.0002_issue_103... OK', output.getvalue()) From 1e0a7cdd716a0d2c642a47a6557b09158c9dde61 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 14:02:44 +0200 Subject: [PATCH 11/15] Renamed TestNotTransactional to NotTransactionalTests for consistency --- tests/django_hstore_tests/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/django_hstore_tests/tests.py b/tests/django_hstore_tests/tests.py index dcc2c47..ad7f5d2 100644 --- a/tests/django_hstore_tests/tests.py +++ b/tests/django_hstore_tests/tests.py @@ -1639,7 +1639,7 @@ class SchemaDataBag(models.Model): ]) -class NotTransactionalTests(SimpleTestCase): +class TestNotTransactional(SimpleTestCase): if DJANGO_VERSION[:2] >= (1, 6): def test_hstore_registring_in_transaction_block(self): obj1 = DataBag.objects.create(name='alpha1', data={'v': '1', 'v2': '3'}) From ba5a72276f6e8fc79b3887cfe61a2433809c5977 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 14:56:46 +0200 Subject: [PATCH 12/15] Fixed "connection already closed" error in django 1.8 --- tests/django_hstore_tests/tests.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/django_hstore_tests/tests.py b/tests/django_hstore_tests/tests.py index ad7f5d2..1df8ee3 100644 --- a/tests/django_hstore_tests/tests.py +++ b/tests/django_hstore_tests/tests.py @@ -1640,11 +1640,16 @@ class SchemaDataBag(models.Model): class TestNotTransactional(SimpleTestCase): + if DJANGO_VERSION[:2] >= (1, 8): + def setUp(self): + # avoid error "connection already closed" + connection.connect() + if DJANGO_VERSION[:2] >= (1, 6): def test_hstore_registring_in_transaction_block(self): obj1 = DataBag.objects.create(name='alpha1', data={'v': '1', 'v2': '3'}) obj2 = DataBag.objects.create(name='alpha2', data={'v': '1', 'v2': '3'}) - # Close any existing connection previously do anything + # Close any existing connection before doing anything connection.close() with transaction.atomic(): qs = DataBag.objects.filter(name__in=["alpha2", "alpha1"]) @@ -1656,7 +1661,7 @@ def test_hstore_registring_in_transaction_block(self): def test_hstore_registring_in_transaction_block(self): obj1 = DataBag.objects.create(name='alpha1', data={'v': '1', 'v2': '3'}) obj2 = DataBag.objects.create(name='alpha2', data={'v': '1', 'v2': '3'}) - # Close any existing connection previously do anything + # Close any existing connection before doing anything connection.close() with transaction.commit_on_success(): qs = DataBag.objects.filter(name__in=["alpha2", "alpha1"]) From 661251cd98a9c381bcec75b3e6456af2d5a3317f Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 15:05:31 +0200 Subject: [PATCH 13/15] Removed accidental executable flags --- .coveragerc | 0 .gitignore | 0 .landscape.yml | 0 .travis.yml | 0 AUTHORS | 0 CONTRIBUTING.rst | 0 LICENSE | 0 README.rst | 0 django_hstore/compat.py | 0 django_hstore/descriptors.py | 0 django_hstore/dict.py | 0 django_hstore/exceptions.py | 0 django_hstore/forms.py | 0 django_hstore/hstore.py | 0 django_hstore/managers.py | 0 django_hstore/models.py | 0 .../static/admin/js/django_hstore/hstore-widget.js | 0 .../static/admin/js/django_hstore/underscore-min.js | 0 django_hstore/templates/hstore_default_widget.html | 0 .../templates/hstore_grappelli_widget.html | 0 django_hstore/utils.py | 0 django_hstore/widgets.py | 0 doc/doc.asciidoc | 0 doc/images/deafult-admin-widget-raw.png | Bin doc/images/deafult-admin-widget.png | Bin doc/images/hstore-widget-raw.png | Bin doc/images/hstore-widget.png | Bin requirements.txt | 0 setup.cfg | 0 tests/__init__.py | 0 tests/django_hstore_tests/admin.py | 0 tests/django_hstore_tests/models.py | 0 tests/local_settings_psycopg.py.example | 0 tests/settings.py | 0 tests/settings_psycopg.py | 0 tests/urls.py | 0 36 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .coveragerc mode change 100755 => 100644 .gitignore mode change 100755 => 100644 .landscape.yml mode change 100755 => 100644 .travis.yml mode change 100755 => 100644 AUTHORS mode change 100755 => 100644 CONTRIBUTING.rst mode change 100755 => 100644 LICENSE mode change 100755 => 100644 README.rst mode change 100755 => 100644 django_hstore/compat.py mode change 100755 => 100644 django_hstore/descriptors.py mode change 100755 => 100644 django_hstore/dict.py mode change 100755 => 100644 django_hstore/exceptions.py mode change 100755 => 100644 django_hstore/forms.py mode change 100755 => 100644 django_hstore/hstore.py mode change 100755 => 100644 django_hstore/managers.py mode change 100755 => 100644 django_hstore/models.py mode change 100755 => 100644 django_hstore/static/admin/js/django_hstore/hstore-widget.js mode change 100755 => 100644 django_hstore/static/admin/js/django_hstore/underscore-min.js mode change 100755 => 100644 django_hstore/templates/hstore_default_widget.html mode change 100755 => 100644 django_hstore/templates/hstore_grappelli_widget.html mode change 100755 => 100644 django_hstore/utils.py mode change 100755 => 100644 django_hstore/widgets.py mode change 100755 => 100644 doc/doc.asciidoc mode change 100755 => 100644 doc/images/deafult-admin-widget-raw.png mode change 100755 => 100644 doc/images/deafult-admin-widget.png mode change 100755 => 100644 doc/images/hstore-widget-raw.png mode change 100755 => 100644 doc/images/hstore-widget.png mode change 100755 => 100644 requirements.txt mode change 100755 => 100644 setup.cfg mode change 100755 => 100644 tests/__init__.py mode change 100755 => 100644 tests/django_hstore_tests/admin.py mode change 100755 => 100644 tests/django_hstore_tests/models.py mode change 100755 => 100644 tests/local_settings_psycopg.py.example mode change 100755 => 100644 tests/settings.py mode change 100755 => 100644 tests/settings_psycopg.py mode change 100755 => 100644 tests/urls.py diff --git a/.coveragerc b/.coveragerc old mode 100755 new mode 100644 diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/.landscape.yml b/.landscape.yml old mode 100755 new mode 100644 diff --git a/.travis.yml b/.travis.yml old mode 100755 new mode 100644 diff --git a/AUTHORS b/AUTHORS old mode 100755 new mode 100644 diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst old mode 100755 new mode 100644 diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 diff --git a/README.rst b/README.rst old mode 100755 new mode 100644 diff --git a/django_hstore/compat.py b/django_hstore/compat.py old mode 100755 new mode 100644 diff --git a/django_hstore/descriptors.py b/django_hstore/descriptors.py old mode 100755 new mode 100644 diff --git a/django_hstore/dict.py b/django_hstore/dict.py old mode 100755 new mode 100644 diff --git a/django_hstore/exceptions.py b/django_hstore/exceptions.py old mode 100755 new mode 100644 diff --git a/django_hstore/forms.py b/django_hstore/forms.py old mode 100755 new mode 100644 diff --git a/django_hstore/hstore.py b/django_hstore/hstore.py old mode 100755 new mode 100644 diff --git a/django_hstore/managers.py b/django_hstore/managers.py old mode 100755 new mode 100644 diff --git a/django_hstore/models.py b/django_hstore/models.py old mode 100755 new mode 100644 diff --git a/django_hstore/static/admin/js/django_hstore/hstore-widget.js b/django_hstore/static/admin/js/django_hstore/hstore-widget.js old mode 100755 new mode 100644 diff --git a/django_hstore/static/admin/js/django_hstore/underscore-min.js b/django_hstore/static/admin/js/django_hstore/underscore-min.js old mode 100755 new mode 100644 diff --git a/django_hstore/templates/hstore_default_widget.html b/django_hstore/templates/hstore_default_widget.html old mode 100755 new mode 100644 diff --git a/django_hstore/templates/hstore_grappelli_widget.html b/django_hstore/templates/hstore_grappelli_widget.html old mode 100755 new mode 100644 diff --git a/django_hstore/utils.py b/django_hstore/utils.py old mode 100755 new mode 100644 diff --git a/django_hstore/widgets.py b/django_hstore/widgets.py old mode 100755 new mode 100644 diff --git a/doc/doc.asciidoc b/doc/doc.asciidoc old mode 100755 new mode 100644 diff --git a/doc/images/deafult-admin-widget-raw.png b/doc/images/deafult-admin-widget-raw.png old mode 100755 new mode 100644 diff --git a/doc/images/deafult-admin-widget.png b/doc/images/deafult-admin-widget.png old mode 100755 new mode 100644 diff --git a/doc/images/hstore-widget-raw.png b/doc/images/hstore-widget-raw.png old mode 100755 new mode 100644 diff --git a/doc/images/hstore-widget.png b/doc/images/hstore-widget.png old mode 100755 new mode 100644 diff --git a/requirements.txt b/requirements.txt old mode 100755 new mode 100644 diff --git a/setup.cfg b/setup.cfg old mode 100755 new mode 100644 diff --git a/tests/__init__.py b/tests/__init__.py old mode 100755 new mode 100644 diff --git a/tests/django_hstore_tests/admin.py b/tests/django_hstore_tests/admin.py old mode 100755 new mode 100644 diff --git a/tests/django_hstore_tests/models.py b/tests/django_hstore_tests/models.py old mode 100755 new mode 100644 diff --git a/tests/local_settings_psycopg.py.example b/tests/local_settings_psycopg.py.example old mode 100755 new mode 100644 diff --git a/tests/settings.py b/tests/settings.py old mode 100755 new mode 100644 diff --git a/tests/settings_psycopg.py b/tests/settings_psycopg.py old mode 100755 new mode 100644 diff --git a/tests/urls.py b/tests/urls.py old mode 100755 new mode 100644 From 96377e4c3122a0bbfa31f4c3706b68ae0eced173 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 15:19:23 +0200 Subject: [PATCH 14/15] Dropped support for django 1.5 as per deprecation policy --- django_hstore/query.py | 22 +++------------------- doc/doc.asciidoc | 2 +- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/django_hstore/query.py b/django_hstore/query.py index c42a640..d4254da 100644 --- a/django_hstore/query.py +++ b/django_hstore/query.py @@ -29,24 +29,8 @@ def updater(self, *args, **params): self._for_write = True query = method(self, self.query.clone(UpdateQuery), *args, **params) forced_managed = False - # django >= 1.6 - if VERSION[:2] >= (1, 6): - with transaction.atomic(using=self.db): - rows = query.get_compiler(self.db).execute_sql(None) - # django <= 1.5 - TODO: remove soon - else: - if not transaction.is_managed(using=self.db): - transaction.enter_transaction_management(using=self.db) - forced_managed = True - try: - rows = query.get_compiler(self.db).execute_sql(None) - if forced_managed: - transaction.commit(using=self.db) - else: - transaction.commit_unless_managed(using=self.db) - finally: - if forced_managed: - transaction.leave_transaction_management(using=self.db) + with transaction.atomic(using=self.db): + rows = query.get_compiler(self.db).execute_sql(None) self._result_cache = None return rows updater.alters_data = True @@ -87,7 +71,7 @@ def add(self, data, *args, **kwargs): # FIXME: this method shuld be more clear. def make_atom(self, child, qn, connection): lvalue, lookup_type, value_annot, param = child - kwargs = {'connection': connection} if VERSION[:2] >= (1, 3) else {} + kwargs = {'connection': connection} if lvalue and lvalue.field and hasattr(lvalue.field, 'db_type') and lvalue.field.db_type(**kwargs) == 'hstore': try: diff --git a/doc/doc.asciidoc b/doc/doc.asciidoc index 78aa880..b2a6584 100644 --- a/doc/doc.asciidoc +++ b/doc/doc.asciidoc @@ -111,7 +111,7 @@ Requirements ^^^^^^^^^^^^ - Python 2.6, 2.7 or 3.3+ -- Django 1.5, 1.6 and 1.7 +- Django 1.6, 1.7 and 1.8 - Psycopg2 2.4.3+ - PostgreSQL 9.0+ From f9462a00c34eed583786baa3af58ea84c638303d Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Sun, 7 Jun 2015 15:29:40 +0200 Subject: [PATCH 15/15] Added test_manager to ensure HStoreGeoManager works in django 1.8 --- tests/django_hstore_tests/tests.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/django_hstore_tests/tests.py b/tests/django_hstore_tests/tests.py index 1df8ee3..d56b487 100644 --- a/tests/django_hstore_tests/tests.py +++ b/tests/django_hstore_tests/tests.py @@ -1941,6 +1941,13 @@ def test_location_geomanager(self): d1 = Location.objects.filter(point__distance_lte=(self.pnt1, 70000)) self.assertEqual(d1.count(), 2) + def test_manager(self): + from django_hstore.managers import HStoreGeoManager + isinstance(Location.objects, HStoreGeoManager) + hasattr(Location.objects, 'hpeek') + hasattr(Location.objects, 'hslice') + hasattr(Location.objects, 'hkeys') + # noqa class TestReferencesFieldPlusGIS(TestDictionaryFieldPlusGIS): """ Test ReferenceField with gis backend """