From 037ce4318b1ea1b99a946d3a70ae2796731ecb1a Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Tue, 21 Apr 2009 22:35:04 +0000 Subject: [PATCH] Fixed #10839 -- `GeoQuery` now unpickles properly on Oracle. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10615 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/gis/db/models/sql/query.py | 16 ++++++++++++++++ django/contrib/gis/tests/relatedapp/tests.py | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/django/contrib/gis/db/models/sql/query.py b/django/contrib/gis/db/models/sql/query.py index 6995771cd6..cf1ccf6483 100644 --- a/django/contrib/gis/db/models/sql/query.py +++ b/django/contrib/gis/db/models/sql/query.py @@ -33,6 +33,13 @@ class GeoQuery(sql.Query): self.transformed_srid = None self.extra_select_fields = {} + if SpatialBackend.oracle: + # Have to override this so that GeoQuery, instead of OracleQuery, + # is returned when unpickling. + def __reduce__(self): + callable, args, data = super(GeoQuery, self).__reduce__() + return (unpickle_geoquery, (), data) + def clone(self, *args, **kwargs): obj = super(GeoQuery, self).clone(*args, **kwargs) # Customized selection dictionary and transformed srid flag have @@ -332,3 +339,12 @@ class GeoQuery(sql.Query): # Otherwise, check by the given field name -- which may be # a lookup to a _related_ geographic field. return GeoWhereNode._check_geo_field(self.model._meta, field_name) + +if SpatialBackend.oracle: + def unpickle_geoquery(): + """ + Utility function, called by Python's unpickling machinery, that handles + unpickling of GeoQuery subclasses of OracleQuery. + """ + return GeoQuery.__new__(GeoQuery) + unpickle_geoquery.__safe_for_unpickling__ = True diff --git a/django/contrib/gis/tests/relatedapp/tests.py b/django/contrib/gis/tests/relatedapp/tests.py index 7df2cc2b3d..77f6c73bb6 100644 --- a/django/contrib/gis/tests/relatedapp/tests.py +++ b/django/contrib/gis/tests/relatedapp/tests.py @@ -222,6 +222,15 @@ class RelatedGeoModelTest(unittest.TestCase): self.failUnless('Aurora' in names) self.failUnless('Kecksburg' in names) + def test11_geoquery_pickle(self): + "Ensuring GeoQuery objects are unpickled correctly. See #10839." + import pickle + from django.contrib.gis.db.models.sql import GeoQuery + qs = City.objects.all() + q_str = pickle.dumps(qs.query) + q = pickle.loads(q_str) + self.assertEqual(GeoQuery, q.__class__) + # TODO: Related tests for KML, GML, and distance lookups. def suite():