mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Refs #27736 -- Used decorators for GIS lookup registration.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							24d53786d4
						
					
				
				
					commit
					d47de2e09d
				
			| @@ -1,5 +1,6 @@ | ||||
| from django.db.models import *  # NOQA isort:skip | ||||
| from django.db.models import __all__ as models_all  # isort:skip | ||||
| import django.contrib.gis.db.models.lookups  # NOQA | ||||
| from django.contrib.gis.db.models.aggregates import *  # NOQA | ||||
| from django.contrib.gis.db.models.aggregates import __all__ as aggregates_all | ||||
| from django.contrib.gis.db.models.fields import ( | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| from collections import defaultdict | ||||
|  | ||||
| from django.contrib.gis import forms, gdal | ||||
| from django.contrib.gis.db.models.lookups import ( | ||||
|     RasterBandTransform, gis_lookups, | ||||
| ) | ||||
| from django.contrib.gis.db.models.proxy import SpatialProxy | ||||
| from django.contrib.gis.gdal.error import GDALException | ||||
| from django.contrib.gis.geometry.backend import Geometry, GeometryException | ||||
| @@ -243,10 +240,6 @@ class BaseSpatialField(Field): | ||||
|             return obj | ||||
|  | ||||
|  | ||||
| for klass in gis_lookups.values(): | ||||
|     BaseSpatialField.register_lookup(klass) | ||||
|  | ||||
|  | ||||
| class GeometryField(GeoSelectFormatMixin, BaseSpatialField): | ||||
|     """ | ||||
|     The base Geometry field -- maps to the OpenGIS Specification Geometry type. | ||||
| @@ -429,6 +422,7 @@ class RasterField(BaseSpatialField): | ||||
|         setattr(cls, self.attname, SpatialProxy(gdal.GDALRaster, self)) | ||||
|  | ||||
|     def get_transform(self, name): | ||||
|         from django.contrib.gis.db.models.lookups import RasterBandTransform | ||||
|         try: | ||||
|             band_index = int(name) | ||||
|             return type( | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| import re | ||||
|  | ||||
| from django.contrib.gis.db.models.fields import BaseSpatialField | ||||
| from django.db.models.expressions import Col, Expression | ||||
| from django.db.models.lookups import Lookup, Transform | ||||
| from django.db.models.sql.query import Query | ||||
|  | ||||
| gis_lookups = {} | ||||
|  | ||||
|  | ||||
| class RasterBandTransform(Transform): | ||||
|     def as_sql(self, compiler, connection): | ||||
| @@ -107,6 +106,7 @@ class GISLookup(Lookup): | ||||
| # Geometry operators | ||||
| # ------------------ | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class OverlapsLeftLookup(GISLookup): | ||||
|     """ | ||||
|     The overlaps_left operator returns true if A's bounding box overlaps or is to the | ||||
| @@ -115,9 +115,7 @@ class OverlapsLeftLookup(GISLookup): | ||||
|     lookup_name = 'overlaps_left' | ||||
|  | ||||
|  | ||||
| gis_lookups['overlaps_left'] = OverlapsLeftLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class OverlapsRightLookup(GISLookup): | ||||
|     """ | ||||
|     The 'overlaps_right' operator returns true if A's bounding box overlaps or is to the | ||||
| @@ -126,9 +124,7 @@ class OverlapsRightLookup(GISLookup): | ||||
|     lookup_name = 'overlaps_right' | ||||
|  | ||||
|  | ||||
| gis_lookups['overlaps_right'] = OverlapsRightLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class OverlapsBelowLookup(GISLookup): | ||||
|     """ | ||||
|     The 'overlaps_below' operator returns true if A's bounding box overlaps or is below | ||||
| @@ -137,9 +133,7 @@ class OverlapsBelowLookup(GISLookup): | ||||
|     lookup_name = 'overlaps_below' | ||||
|  | ||||
|  | ||||
| gis_lookups['overlaps_below'] = OverlapsBelowLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class OverlapsAboveLookup(GISLookup): | ||||
|     """ | ||||
|     The 'overlaps_above' operator returns true if A's bounding box overlaps or is above | ||||
| @@ -148,9 +142,7 @@ class OverlapsAboveLookup(GISLookup): | ||||
|     lookup_name = 'overlaps_above' | ||||
|  | ||||
|  | ||||
| gis_lookups['overlaps_above'] = OverlapsAboveLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class LeftLookup(GISLookup): | ||||
|     """ | ||||
|     The 'left' operator returns true if A's bounding box is strictly to the left | ||||
| @@ -159,9 +151,7 @@ class LeftLookup(GISLookup): | ||||
|     lookup_name = 'left' | ||||
|  | ||||
|  | ||||
| gis_lookups['left'] = LeftLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class RightLookup(GISLookup): | ||||
|     """ | ||||
|     The 'right' operator returns true if A's bounding box is strictly to the right | ||||
| @@ -170,9 +160,7 @@ class RightLookup(GISLookup): | ||||
|     lookup_name = 'right' | ||||
|  | ||||
|  | ||||
| gis_lookups['right'] = RightLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class StrictlyBelowLookup(GISLookup): | ||||
|     """ | ||||
|     The 'strictly_below' operator returns true if A's bounding box is strictly below B's | ||||
| @@ -181,9 +169,7 @@ class StrictlyBelowLookup(GISLookup): | ||||
|     lookup_name = 'strictly_below' | ||||
|  | ||||
|  | ||||
| gis_lookups['strictly_below'] = StrictlyBelowLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class StrictlyAboveLookup(GISLookup): | ||||
|     """ | ||||
|     The 'strictly_above' operator returns true if A's bounding box is strictly above B's | ||||
| @@ -192,9 +178,7 @@ class StrictlyAboveLookup(GISLookup): | ||||
|     lookup_name = 'strictly_above' | ||||
|  | ||||
|  | ||||
| gis_lookups['strictly_above'] = StrictlyAboveLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class SameAsLookup(GISLookup): | ||||
|     """ | ||||
|     The "~=" operator is the "same as" operator. It tests actual geometric | ||||
| @@ -204,17 +188,10 @@ class SameAsLookup(GISLookup): | ||||
|     lookup_name = 'same_as' | ||||
|  | ||||
|  | ||||
| gis_lookups['same_as'] = SameAsLookup | ||||
|  | ||||
|  | ||||
| class ExactLookup(SameAsLookup): | ||||
|     # Alias of same_as | ||||
|     lookup_name = 'exact' | ||||
|  | ||||
|  | ||||
| gis_lookups['exact'] = ExactLookup | ||||
| BaseSpatialField.register_lookup(SameAsLookup, 'exact') | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class BBContainsLookup(GISLookup): | ||||
|     """ | ||||
|     The 'bbcontains' operator returns true if A's bounding box completely contains | ||||
| @@ -223,9 +200,7 @@ class BBContainsLookup(GISLookup): | ||||
|     lookup_name = 'bbcontains' | ||||
|  | ||||
|  | ||||
| gis_lookups['bbcontains'] = BBContainsLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class BBOverlapsLookup(GISLookup): | ||||
|     """ | ||||
|     The 'bboverlaps' operator returns true if A's bounding box overlaps B's bounding box. | ||||
| @@ -233,9 +208,7 @@ class BBOverlapsLookup(GISLookup): | ||||
|     lookup_name = 'bboverlaps' | ||||
|  | ||||
|  | ||||
| gis_lookups['bboverlaps'] = BBOverlapsLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class ContainedLookup(GISLookup): | ||||
|     """ | ||||
|     The 'contained' operator returns true if A's bounding box is completely contained | ||||
| @@ -244,69 +217,51 @@ class ContainedLookup(GISLookup): | ||||
|     lookup_name = 'contained' | ||||
|  | ||||
|  | ||||
| gis_lookups['contained'] = ContainedLookup | ||||
|  | ||||
|  | ||||
| # ------------------ | ||||
| # Geometry functions | ||||
| # ------------------ | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class ContainsLookup(GISLookup): | ||||
|     lookup_name = 'contains' | ||||
|  | ||||
|  | ||||
| gis_lookups['contains'] = ContainsLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class ContainsProperlyLookup(GISLookup): | ||||
|     lookup_name = 'contains_properly' | ||||
|  | ||||
|  | ||||
| gis_lookups['contains_properly'] = ContainsProperlyLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class CoveredByLookup(GISLookup): | ||||
|     lookup_name = 'coveredby' | ||||
|  | ||||
|  | ||||
| gis_lookups['coveredby'] = CoveredByLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class CoversLookup(GISLookup): | ||||
|     lookup_name = 'covers' | ||||
|  | ||||
|  | ||||
| gis_lookups['covers'] = CoversLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class CrossesLookup(GISLookup): | ||||
|     lookup_name = 'crosses' | ||||
|  | ||||
|  | ||||
| gis_lookups['crosses'] = CrossesLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class DisjointLookup(GISLookup): | ||||
|     lookup_name = 'disjoint' | ||||
|  | ||||
|  | ||||
| gis_lookups['disjoint'] = DisjointLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class EqualsLookup(GISLookup): | ||||
|     lookup_name = 'equals' | ||||
|  | ||||
|  | ||||
| gis_lookups['equals'] = EqualsLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class IntersectsLookup(GISLookup): | ||||
|     lookup_name = 'intersects' | ||||
|  | ||||
|  | ||||
| gis_lookups['intersects'] = IntersectsLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class IsValidLookup(GISLookup): | ||||
|     lookup_name = 'isvalid' | ||||
|     sql_template = '%(func)s(%(lhs)s)' | ||||
| @@ -322,16 +277,12 @@ class IsValidLookup(GISLookup): | ||||
|         return sql, params | ||||
|  | ||||
|  | ||||
| gis_lookups['isvalid'] = IsValidLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class OverlapsLookup(GISLookup): | ||||
|     lookup_name = 'overlaps' | ||||
|  | ||||
|  | ||||
| gis_lookups['overlaps'] = OverlapsLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class RelateLookup(GISLookup): | ||||
|     lookup_name = 'relate' | ||||
|     sql_template = '%(func)s(%(lhs)s, %(rhs)s, %%s)' | ||||
| @@ -351,23 +302,16 @@ class RelateLookup(GISLookup): | ||||
|         return super().get_db_prep_lookup(value, connection) | ||||
|  | ||||
|  | ||||
| gis_lookups['relate'] = RelateLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class TouchesLookup(GISLookup): | ||||
|     lookup_name = 'touches' | ||||
|  | ||||
|  | ||||
| gis_lookups['touches'] = TouchesLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class WithinLookup(GISLookup): | ||||
|     lookup_name = 'within' | ||||
|  | ||||
|  | ||||
| gis_lookups['within'] = WithinLookup | ||||
|  | ||||
|  | ||||
| class DistanceLookupBase(GISLookup): | ||||
|     distance = True | ||||
|     sql_template = '%(func)s(%(lhs)s, %(rhs)s) %(op)s %(value)s' | ||||
| @@ -400,37 +344,27 @@ class DistanceLookupBase(GISLookup): | ||||
|         return (rhs, params) | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class DWithinLookup(DistanceLookupBase): | ||||
|     lookup_name = 'dwithin' | ||||
|     sql_template = '%(func)s(%(lhs)s, %(rhs)s, %%s)' | ||||
|  | ||||
|  | ||||
| gis_lookups['dwithin'] = DWithinLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class DistanceGTLookup(DistanceLookupBase): | ||||
|     lookup_name = 'distance_gt' | ||||
|  | ||||
|  | ||||
| gis_lookups['distance_gt'] = DistanceGTLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class DistanceGTELookup(DistanceLookupBase): | ||||
|     lookup_name = 'distance_gte' | ||||
|  | ||||
|  | ||||
| gis_lookups['distance_gte'] = DistanceGTELookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class DistanceLTLookup(DistanceLookupBase): | ||||
|     lookup_name = 'distance_lt' | ||||
|  | ||||
|  | ||||
| gis_lookups['distance_lt'] = DistanceLTLookup | ||||
|  | ||||
|  | ||||
| @BaseSpatialField.register_lookup | ||||
| class DistanceLTELookup(DistanceLookupBase): | ||||
|     lookup_name = 'distance_lte' | ||||
|  | ||||
|  | ||||
| gis_lookups['distance_lte'] = DistanceLTELookup | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| import json | ||||
|  | ||||
| from django.contrib.gis.db.models.fields import BaseSpatialField | ||||
| from django.contrib.gis.db.models.functions import Distance | ||||
| from django.contrib.gis.db.models.lookups import ( | ||||
|     DistanceLookupBase, gis_lookups, | ||||
| ) | ||||
| from django.contrib.gis.db.models.lookups import DistanceLookupBase, GISLookup | ||||
| from django.contrib.gis.gdal import HAS_GDAL | ||||
| from django.contrib.gis.geos import GEOSGeometry | ||||
| from django.contrib.gis.measure import D | ||||
| @@ -130,7 +129,9 @@ class RasterFieldTest(TransactionTestCase): | ||||
|         stx_pnt.transform(3086) | ||||
|  | ||||
|         # Loop through all the GIS lookups. | ||||
|         for name, lookup in gis_lookups.items(): | ||||
|         for name, lookup in BaseSpatialField.get_lookups().items(): | ||||
|             if not isinstance(lookup, GISLookup): | ||||
|                 continue | ||||
|             # Construct lookup filter strings. | ||||
|             combo_keys = [ | ||||
|                 field + name for field in [ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user