mirror of https://github.com/django/django.git
Fixed #28380 -- Excluded null geometries in SpatiaLite geometry lookups.
This commit is contained in:
parent
a8bb493556
commit
da0fb5b1ec
|
@ -17,6 +17,12 @@ from django.utils.functional import cached_property
|
|||
from django.utils.version import get_version_tuple
|
||||
|
||||
|
||||
class SpatialiteNullCheckOperator(SpatialOperator):
|
||||
def as_sql(self, connection, lookup, template_params, sql_params):
|
||||
sql, params = super().as_sql(connection, lookup, template_params, sql_params)
|
||||
return '%s > 0' % sql, params
|
||||
|
||||
|
||||
class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||
name = 'spatialite'
|
||||
spatialite = True
|
||||
|
@ -33,15 +39,15 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
|
||||
gis_operators = {
|
||||
# Binary predicates
|
||||
'equals': SpatialOperator(func='Equals'),
|
||||
'disjoint': SpatialOperator(func='Disjoint'),
|
||||
'touches': SpatialOperator(func='Touches'),
|
||||
'crosses': SpatialOperator(func='Crosses'),
|
||||
'within': SpatialOperator(func='Within'),
|
||||
'overlaps': SpatialOperator(func='Overlaps'),
|
||||
'contains': SpatialOperator(func='Contains'),
|
||||
'intersects': SpatialOperator(func='Intersects'),
|
||||
'relate': SpatialOperator(func='Relate'),
|
||||
'equals': SpatialiteNullCheckOperator(func='Equals'),
|
||||
'disjoint': SpatialiteNullCheckOperator(func='Disjoint'),
|
||||
'touches': SpatialiteNullCheckOperator(func='Touches'),
|
||||
'crosses': SpatialiteNullCheckOperator(func='Crosses'),
|
||||
'within': SpatialiteNullCheckOperator(func='Within'),
|
||||
'overlaps': SpatialiteNullCheckOperator(func='Overlaps'),
|
||||
'contains': SpatialiteNullCheckOperator(func='Contains'),
|
||||
'intersects': SpatialiteNullCheckOperator(func='Intersects'),
|
||||
'relate': SpatialiteNullCheckOperator(func='Relate'),
|
||||
# Returns true if B's bounding box completely contains A's bounding box.
|
||||
'contained': SpatialOperator(func='MbrWithin'),
|
||||
# Returns true if A's bounding box completely contains B's bounding box.
|
||||
|
@ -49,8 +55,8 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
|||
# Returns true if A's bounding box overlaps B's bounding box.
|
||||
'bboverlaps': SpatialOperator(func='MbrOverlaps'),
|
||||
# These are implemented here as synonyms for Equals
|
||||
'same_as': SpatialOperator(func='Equals'),
|
||||
'exact': SpatialOperator(func='Equals'),
|
||||
'same_as': SpatialiteNullCheckOperator(func='Equals'),
|
||||
'exact': SpatialiteNullCheckOperator(func='Equals'),
|
||||
# Distance predicates
|
||||
'dwithin': SpatialOperator(func='PtDistWithin'),
|
||||
}
|
||||
|
|
|
@ -403,6 +403,27 @@ class GeoLookupTest(TestCase):
|
|||
State.objects.filter(name='Northern Mariana Islands').update(poly=None)
|
||||
self.assertIsNone(State.objects.get(name='Northern Mariana Islands').poly)
|
||||
|
||||
@skipUnlessDBFeature('supports_null_geometries', 'supports_crosses_lookup', 'supports_relate_lookup')
|
||||
def test_null_geometries_excluded_in_lookups(self):
|
||||
"""NULL features are excluded in spatial lookup functions."""
|
||||
null = State.objects.create(name='NULL', poly=None)
|
||||
queries = [
|
||||
('equals', Point(1, 1)),
|
||||
('disjoint', Point(1, 1)),
|
||||
('touches', Point(1, 1)),
|
||||
('crosses', LineString((0, 0), (1, 1), (5, 5))),
|
||||
('within', Point(1, 1)),
|
||||
('overlaps', LineString((0, 0), (1, 1), (5, 5))),
|
||||
('contains', LineString((0, 0), (1, 1), (5, 5))),
|
||||
('intersects', LineString((0, 0), (1, 1), (5, 5))),
|
||||
('relate', (Point(1, 1), 'T*T***FF*')),
|
||||
('same_as', Point(1, 1)),
|
||||
('exact', Point(1, 1)),
|
||||
]
|
||||
for lookup, geom in queries:
|
||||
with self.subTest(lookup=lookup):
|
||||
self.assertNotIn(null, State.objects.filter(**{'poly__%s' % lookup: geom}))
|
||||
|
||||
@skipUnlessDBFeature("supports_relate_lookup")
|
||||
def test_relate_lookup(self):
|
||||
"Testing the 'relate' lookup type."
|
||||
|
|
Loading…
Reference in New Issue