Changeset 5762
- Timestamp:
- 07/25/07 21:18:26 (1 year ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis/django/contrib/gis/db/models/fields/__init__.py
r5657 r5762 6 6 from django.utils.functional import curry 7 7 from django.contrib.gis.geos import GEOSGeometry, GEOSException 8 from types import StringType 8 9 9 10 #TODO: Flesh out widgets. 10 #TODO: GEOS and GDAL/OGR operations through fields as proxy.11 #TODO: pythonic usage, like "for point in zip.polygon" and "if point in polygon".12 11 13 12 class GeometryField(Field): … … 115 114 116 115 def get_db_prep_lookup(self, lookup_type, value): 117 " ""Returns field's value prepared for database lookup; the SRID of the geometry is118 i ncluded by default in these queries."""116 "Returns field's value prepared for database lookup, accepts WKT and GEOS Geometries for the value." 117 if not bool(value): return None 119 118 if lookup_type in POSTGIS_TERMS: 120 return [value and ("SRID=%d;%s" % (self._srid, value)) or None] 121 raise TypeError("Field has invalid lookup: %s" % lookup_type) 119 if isinstance(value, GEOSGeometry): 120 # GEOSGeometry instance passed in. 121 if value.srid != self._srid: 122 # Returning a dictionary instructs the parse_lookup() to add what's in the 'where' key 123 # to the where parameters, since we need to transform the geometry in the query. 124 return {'where' : "Transform(%s,%s)", 125 'params' : [value, self._srid] 126 } 127 else: 128 # Just return the GEOSGeometry, it has its own psycopg2 adaptor. 129 return [value] 130 elif isinstance(value, StringType): 131 # String instance passed in, assuming WKT. 132 # TODO: Any validation needed here to prevent SQL injection? 133 return ["SRID=%d;%s" % (self._srid, value)] 134 else: 135 raise TypeError("Invalid type (%s) used for field lookup value." % str(type(value))) 136 else: 137 raise TypeError("Field has invalid lookup: %s" % lookup_type) 122 138 123 139 def get_db_prep_save(self, value): 124 "Making sure the SRID is included before saving." 125 return value and ("SRID=%d;%s" % (self._srid, value)) or None 140 "Prepares the value for saving in the database." 141 if not bool(value): return None 142 if isinstance(value, GEOSGeometry): 143 return value 144 else: 145 return ("SRID=%d;%s" % (self._srid, wkt)) 146 147 def get_placeholder(self, value): 148 "Provides a proper substitution value for " 149 if isinstance(value, GEOSGeometry) and value.srid != self._srid: 150 # Adding Transform() to the SQL placeholder. 151 return 'Transform(%%s, %s)' % self._srid 152 else: 153 return '%s' 126 154 127 155 def get_manipulator_field_objs(self): django/branches/gis/django/contrib/gis/db/models/postgis.py
r5657 r5762 2 2 # django.db.models.query objects to be customized for PostGIS. 3 3 from django.db import backend 4 from django.db.models.query import LOOKUP_SEPARATOR, fi nd_field, FieldFound, QUERY_TERMS, get_where_clause4 from django.db.models.query import LOOKUP_SEPARATOR, field_choices, find_field, FieldFound, QUERY_TERMS, get_where_clause 5 5 from django.utils.datastructures import SortedDict 6 6 … … 85 85 raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type) 86 86 87 #### query.py overloaded functions #### 88 # parse_lookup() and lookup_inner() are modified from their django/db/models/query.py 89 # counterparts to support constructing SQL for geographic queries. 90 # 91 # Status: Synced with r5609. 92 # 87 93 def parse_lookup(kwarg_items, opts): 88 94 # Helper function that handles converting API kwargs … … 118 124 # term, assume that the query is an __exact 119 125 lookup_type = path.pop() 120 121 126 if lookup_type == 'pk': 122 127 lookup_type = 'exact' … … 134 139 if lookup_type != 'exact': 135 140 raise ValueError, "Cannot use None as a query value" 141 elif callable(value): 142 value = value() 136 143 137 144 joins2, where2, params2 = lookup_inner(path, lookup_type, value, opts, opts.db_table, None) … … 207 214 # Does the name belong to a one-to-one, many-to-one, or regular field? 208 215 field = find_field(name, current_opts.fields, False) 209 210 216 if field: 211 217 if field.rel: # One-to-One/Many-to-one field … … 226 232 pass 227 233 else: # No match found. 228 raise TypeError, "Cannot resolve keyword '%s' into field" % name 234 choices = field_choices(current_opts.many_to_many, False) + \ 235 field_choices(current_opts.get_all_related_many_to_many_objects(), True) + \ 236 field_choices(current_opts.get_all_related_objects(), True) + \ 237 field_choices(current_opts.fields, False) 238 raise TypeError, "Cannot resolve keyword '%s' into field. Choices are: %s" % (name, ", ".join(choices)) 229 239 230 240 # Check whether an intermediate join is required between current_table … … 299 309 # with the get_geo_where_clause() 300 310 if hasattr(field, '_geom'): 301 where.append(get_geo_where_clause(lookup_type, current_table + '.', column, value)) 311 # Getting the geographic where clause. 312 gwc = get_geo_where_clause(lookup_type, current_table + '.', column, value) 313 314 # Getting the geographic parameters from the field. 315 geo_params = field.get_db_prep_lookup(lookup_type, value) 316 317 # If a dictionary was passed back from the field modify the where clause. 318 if isinstance(geo_params, dict): 319 gwc = gwc % geo_params['where'] 320 geo_params = geo_params['params'] 321 where.append(gwc) 322 params.extend(geo_params) 302 323 else: 303 324 where.append(get_where_clause(lookup_type, current_table + '.', column, value)) 304 params.extend(field.get_db_prep_lookup(lookup_type, value))325 params.extend(field.get_db_prep_lookup(lookup_type, value)) 305 326 306 327 return joins, where, params django/branches/gis/django/contrib/gis/db/models/proxy.py
r5657 r5762 25 25 if isinstance(value, GEOSGeometry): 26 26 if value and ((value.srid is None) and (self._field._srid is not None)): 27 value.s et_srid(self._field._srid)27 value.srid = self._field._srid 28 28 29 29 obj.__dict__[self._field.attname] = value
