Changeset 4884
- Timestamp:
- 03/31/07 16:25:29 (2 years ago)
- Files:
-
- django/branches/gis/django/contrib/gis/db/models/fields/__init__.py (modified) (4 diffs)
- django/branches/gis/django/contrib/gis/db/models/GeoMixin.py (added)
- django/branches/gis/django/contrib/gis/db/models/__init__.py (modified) (2 diffs)
- django/branches/gis/django/contrib/gis/db/models/manager.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/db/models/postgis.py (modified) (8 diffs)
- django/branches/gis/django/contrib/gis/db/models/query.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis/django/contrib/gis/db/models/fields/__init__.py
r4851 r4884 1 1 # The Django base Field class. 2 2 from django.db.models.fields import Field 3 from django.oldforms import LargeTextField4 3 from django.contrib.gis.db.models.postgis import POSTGIS_TERMS 5 from geos import geomToWKT, geomFromHEX 4 from django.contrib.gis.oldforms import WKTField 5 from django.utils.functional import curry 6 6 7 7 #TODO: add db.quotename. … … 36 36 return sql 37 37 38 class WKTField(LargeTextField):39 "An oldforms LargeTextField for editing WKT text in the admin."40 41 def render(self, data):42 # PostGIS uses EWKBHEX to store its values internally, converting43 # to WKT for the admin first.44 wkt = geomToWKT(geomFromHEX(data))45 return super(WKTField, self).render(wkt)46 47 38 class GeometryField(Field): 48 39 "The base GIS field -- maps to the OpenGIS Geometry type." … … 65 56 super(GeometryField, self).__init__(**kwargs) 66 57 58 59 def contribute_to_class(self, cls, name): 60 super(GeometryField, self).contribute_to_class(cls, name) 61 62 # Adding the WKT accessor function for geometry 63 setattr(cls, 'get_%s_wkt' % self.name, curry(cls._get_GEOM_wkt, field=self)) 64 setattr(cls, 'get_%s_centroid' % self.name, curry(cls._get_GEOM_centroid, field=self)) 65 setattr(cls, 'get_%s_area' % self.name, curry(cls._get_GEOM_area, field=self)) 67 66 68 67 def get_internal_type(self): … … 99 98 "Using the WKTField (defined above) to be our manipulator." 100 99 return [WKTField] 101 100 102 101 # The OpenGIS Geometry Type Fields 103 102 class PointField(GeometryField): django/branches/gis/django/contrib/gis/db/models/__init__.py
r4851 r4884 2 2 from django.db.models import * 3 3 4 # The GeoManager class.4 # The GeoManager 5 5 from django.contrib.gis.db.models.manager import GeoManager 6 6 … … 11 11 GeometryCollectionField 12 12 13 # The geographic mixin class. 14 from GeoMixin import GeoMixin django/branches/gis/django/contrib/gis/db/models/manager.py
r4787 r4884 3 3 4 4 class GeoManager(Manager): 5 "Overrides Manager to return Geographic QuerySets." 5 6 6 7 def get_query_set(self): 7 8 return GeoQuerySet(model=self.model) 8 9 def geo_filter(self, *args, **kwargs):10 return self.get_query_set().geo_filter(*args, **kwargs)11 12 def geo_exclude(self, *args, **kwargs):13 return self.get_query_set().geo_exclude(*args, **kwargs)django/branches/gis/django/contrib/gis/db/models/postgis.py
r4851 r4884 3 3 from copy import copy 4 4 from django.db import backend 5 from django.db.models.query import LOOKUP_SEPARATOR, find_field, FieldFound 5 from django.db.models.query import LOOKUP_SEPARATOR, find_field, FieldFound, QUERY_TERMS, get_where_clause 6 6 from django.utils.datastructures import SortedDict 7 7 … … 42 42 'equals' : 'Equals', 43 43 'disjoint' : 'Disjoint', 44 'intersects' : 'Intersects',45 44 'touches' : 'Touches', 46 45 'crosses' : 'Crosses', … … 56 55 POSTGIS_TERMS = list(POSTGIS_OPERATORS.keys()) # Getting the operators first 57 56 POSTGIS_TERMS.extend(list(POSTGIS_GEOMETRY_FUNCTIONS.keys())) # Adding on the Geometry Functions 57 POSTGIS_TERMS = tuple(POSTGIS_TERMS) # Making immutable 58 58 59 59 def get_geo_where_clause(lookup_type, table_prefix, field_name, value): … … 73 73 except KeyError: 74 74 pass 75 75 76 76 # For any other lookup type 77 77 if lookup_type == 'isnull': … … 80 80 raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type) 81 81 82 def geo_parse_lookup(kwarg_items, opts):82 def parse_lookup(kwarg_items, opts): 83 83 # Helper function that handles converting API kwargs 84 84 # (e.g. "name__exact": "tom") to SQL. 85 # Returns a tuple of ( tables,joins, where, params).85 # Returns a tuple of (joins, where, params). 86 86 87 87 # 'joins' is a sorted dictionary describing the tables that must be joined … … 113 113 # term, assume that the query is an __exact 114 114 lookup_type = path.pop() 115 115 116 if lookup_type == 'pk': 116 117 lookup_type = 'exact' 117 118 path.append(None) 118 elif len(path) == 0 or lookup_type not in POSTGIS_TERMS:119 elif len(path) == 0 or not ((lookup_type in QUERY_TERMS) or (lookup_type in POSTGIS_TERMS)): 119 120 path.append(lookup_type) 120 121 lookup_type = 'exact' … … 201 202 # Does the name belong to a one-to-one, many-to-one, or regular field? 202 203 field = find_field(name, current_opts.fields, False) 204 203 205 if field: 204 206 if field.rel: # One-to-One/Many-to-one field … … 294 296 where.append(get_geo_where_clause(lookup_type, current_table + '.', column, value)) 295 297 else: 296 raise TypeError, 'Field "%s" (%s) is not a Geometry Field.' % (column, field.__class__.__name__)298 where.append(get_where_clause(lookup_type, current_table + '.', column, value)) 297 299 params.extend(field.get_db_prep_lookup(lookup_type, value)) 298 300 299 301 return joins, where, params 300 django/branches/gis/django/contrib/gis/db/models/query.py
r4787 r4884 1 from django.db.models.query import * 2 from django.contrib.gis.db.models.postgis import geo_parse_lookup 1 from django.db.models.query import Q, QNot, QuerySet 2 from django.contrib.gis.db.models.postgis import parse_lookup 3 import operator 3 4 4 5 class GeoQ(Q): … … 6 7 7 8 def get_sql(self, opts): 8 "Overloaded to use the geo_parse_lookup() function instead of parse_lookup()"9 return geo_parse_lookup(self.kwargs.items(), opts)9 "Overloaded to use our own parse_lookup() function." 10 return parse_lookup(self.kwargs.items(), opts) 10 11 11 12 class GeoQuerySet(QuerySet): 12 13 "Geographical-enabled QuerySet object." 13 14 14 def geo_filter(self, *args, **kwargs): 15 "Returns a new GeoQuerySet instance with the args ANDed to the existing set." 16 return self._geo_filter_or_exclude(None, *args, **kwargs) 15 def __init__(self, model=None): 16 super(GeoQuerySet, self).__init__(model=model) 17 17 18 def geo_exclude(self, *args, **kwargs): 19 "Returns a new GeoQuerySet instance with NOT (args) ANDed to the existing set." 20 return self._geo_filter_or_exclude(QNot, *args, **kwargs) 18 # We only want to use the GeoQ object for our queries 19 self._filters = GeoQ() 21 20 22 def _ geo_filter_or_exclude(self, mapper, *args, **kwargs):21 def _filter_or_exclude(self, mapper, *args, **kwargs): 23 22 # mapper is a callable used to transform Q objects, 24 23 # or None for identity transform
