mirror of https://github.com/django/django.git
[2.0.x] Fixed #29054 -- Fixed a regression where a queryset that annotates with geometry objects crashes.
Made GEOSGeometryBase hashable. Regression in19b2dfd1bf
. Thanks Tim Graham for the review. Backport ofb002a032f9
from master
This commit is contained in:
parent
61c74ae74f
commit
42622b8934
|
@ -144,6 +144,9 @@ class GEOSGeometryBase(GEOSBase):
|
||||||
return False
|
return False
|
||||||
return isinstance(other, GEOSGeometry) and self.srid == other.srid and self.equals_exact(other)
|
return isinstance(other, GEOSGeometry) and self.srid == other.srid and self.equals_exact(other)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash((self.srid, self.wkt))
|
||||||
|
|
||||||
# ### Geometry set-like operations ###
|
# ### Geometry set-like operations ###
|
||||||
# Thanks to Sean Gillies for inspiration:
|
# Thanks to Sean Gillies for inspiration:
|
||||||
# http://lists.gispython.org/pipermail/community/2007-July/001034.html
|
# http://lists.gispython.org/pipermail/community/2007-July/001034.html
|
||||||
|
|
|
@ -17,3 +17,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed regression in the use of ``QuerySet.values_list(..., flat=True)``
|
* Fixed regression in the use of ``QuerySet.values_list(..., flat=True)``
|
||||||
followed by ``annotate()`` (:ticket:`29067`).
|
followed by ``annotate()`` (:ticket:`29067`).
|
||||||
|
|
||||||
|
* Fixed a regression where a queryset that annotates with geometry objects
|
||||||
|
crashes (:ticket:`29054`).
|
||||||
|
|
|
@ -3,10 +3,11 @@ from unittest import skipUnless
|
||||||
from django.contrib.gis.db.models import F, GeometryField, Value, functions
|
from django.contrib.gis.db.models import F, GeometryField, Value, functions
|
||||||
from django.contrib.gis.geos import Point, Polygon
|
from django.contrib.gis.geos import Point, Polygon
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
from django.db.models import Count
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase, skipUnlessDBFeature
|
||||||
|
|
||||||
from ..utils import postgis
|
from ..utils import postgis
|
||||||
from .models import City, ManyPointModel
|
from .models import City, ManyPointModel, MultiFields
|
||||||
|
|
||||||
|
|
||||||
class GeoExpressionsTests(TestCase):
|
class GeoExpressionsTests(TestCase):
|
||||||
|
@ -48,6 +49,17 @@ class GeoExpressionsTests(TestCase):
|
||||||
obj.refresh_from_db()
|
obj.refresh_from_db()
|
||||||
self.assertTrue(obj.point3.equals_exact(p1.transform(3857, clone=True), 0.1))
|
self.assertTrue(obj.point3.equals_exact(p1.transform(3857, clone=True), 0.1))
|
||||||
|
|
||||||
|
def test_multiple_annotation(self):
|
||||||
|
multi_field = MultiFields.objects.create(
|
||||||
|
point=Point(1, 1),
|
||||||
|
city=City.objects.get(name='Houston'),
|
||||||
|
poly=Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))),
|
||||||
|
)
|
||||||
|
qs = City.objects.values('name').annotate(
|
||||||
|
distance=functions.Distance('multifields__point', multi_field.city.point),
|
||||||
|
).annotate(count=Count('multifields'))
|
||||||
|
self.assertTrue(qs.first())
|
||||||
|
|
||||||
@skipUnlessDBFeature('has_Translate_function')
|
@skipUnlessDBFeature('has_Translate_function')
|
||||||
def test_update_with_expression(self):
|
def test_update_with_expression(self):
|
||||||
city = City.objects.create(point=Point(1, 1, srid=4326))
|
city = City.objects.create(point=Point(1, 1, srid=4326))
|
||||||
|
|
|
@ -187,6 +187,22 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
|
||||||
self.assertNotEqual(g, {'foo': 'bar'})
|
self.assertNotEqual(g, {'foo': 'bar'})
|
||||||
self.assertNotEqual(g, False)
|
self.assertNotEqual(g, False)
|
||||||
|
|
||||||
|
def test_hash(self):
|
||||||
|
point_1 = Point(5, 23)
|
||||||
|
point_2 = Point(5, 23, srid=4326)
|
||||||
|
point_3 = Point(5, 23, srid=32632)
|
||||||
|
multipoint_1 = MultiPoint(point_1, srid=4326)
|
||||||
|
multipoint_2 = MultiPoint(point_2)
|
||||||
|
multipoint_3 = MultiPoint(point_3)
|
||||||
|
self.assertNotEqual(hash(point_1), hash(point_2))
|
||||||
|
self.assertNotEqual(hash(point_1), hash(point_3))
|
||||||
|
self.assertNotEqual(hash(point_2), hash(point_3))
|
||||||
|
self.assertNotEqual(hash(multipoint_1), hash(multipoint_2))
|
||||||
|
self.assertEqual(hash(multipoint_2), hash(multipoint_3))
|
||||||
|
self.assertNotEqual(hash(multipoint_1), hash(point_1))
|
||||||
|
self.assertNotEqual(hash(multipoint_2), hash(point_2))
|
||||||
|
self.assertNotEqual(hash(multipoint_3), hash(point_3))
|
||||||
|
|
||||||
def test_eq_with_srid(self):
|
def test_eq_with_srid(self):
|
||||||
"Testing non-equivalence with different srids."
|
"Testing non-equivalence with different srids."
|
||||||
p0 = Point(5, 23)
|
p0 = Point(5, 23)
|
||||||
|
|
Loading…
Reference in New Issue