Commit 037ce431 authored by Justin Bronn's avatar Justin Bronn
Browse files

Fixed #10839 -- `GeoQuery` now unpickles properly on Oracle.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@10615 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent b09f5541
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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
+9 −0
Original line number Diff line number Diff line
@@ -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():