added GeoLocationField with auto index-creation for GEO2D

This commit is contained in:
Florian Schlachter 2010-03-30 00:04:39 +02:00
parent 38b2919c0d
commit 2304dac8e3
2 changed files with 26 additions and 5 deletions

View File

@ -12,7 +12,7 @@ __all__ = ['StringField', 'IntField', 'FloatField', 'BooleanField',
'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField', 'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField',
'ObjectIdField', 'ReferenceField', 'ValidationError', 'ObjectIdField', 'ReferenceField', 'ValidationError',
'DecimalField', 'URLField', 'GenericReferenceField', 'DecimalField', 'URLField', 'GenericReferenceField',
'BinaryField', 'EmailField'] 'BinaryField', 'EmailField', 'GeoLocationField']
RECURSIVE_REFERENCE_CONSTANT = 'self' RECURSIVE_REFERENCE_CONSTANT = 'self'
@ -342,6 +342,23 @@ class DictField(BaseField):
def lookup_member(self, member_name): def lookup_member(self, member_name):
return BaseField(db_field=member_name) return BaseField(db_field=member_name)
class GeoLocationField(DictField):
"""Supports geobased fields"""
def validate(self, value):
"""Make sure that a geo-value is of type (x, y)
"""
if not isinstance(value, tuple) and not isinstance(value, list):
raise ValidationError('GeoLocationField can only hold tuples or lists of (x, y)')
if len(value) <> 2:
raise ValidationError('GeoLocationField must have exactly two elements (x, y)')
def to_mongo(self, value):
return {'x': value[0], 'y': value[1]}
def to_python(self, value):
return value.keys()
class ReferenceField(BaseField): class ReferenceField(BaseField):
"""A reference to a document that will be automatically dereferenced on """A reference to a document that will be automatically dereferenced on

View File

@ -4,7 +4,6 @@ import pymongo
import re import re
import copy import copy
__all__ = ['queryset_manager', 'Q', 'InvalidQueryError', __all__ = ['queryset_manager', 'Q', 'InvalidQueryError',
'InvalidCollectionError'] 'InvalidCollectionError']
@ -242,6 +241,11 @@ class QuerySet(object):
# If _types is being used (for polymorphism), it needs an index # If _types is being used (for polymorphism), it needs an index
if '_types' in self._query: if '_types' in self._query:
self._collection.ensure_index('_types') self._collection.ensure_index('_types')
# Ensure all needed field indexes are created
for field_name, field_instance in self._document._fields.iteritems():
if field_instance.__class__.__name__ == 'GeoLocationField':
self._collection.ensure_index([(field_name, pymongo.GEO2D),])
return self._collection_obj return self._collection_obj
@property @property
@ -297,7 +301,7 @@ class QuerySet(object):
"""Transform a query from Django-style format to Mongo format. """Transform a query from Django-style format to Mongo format.
""" """
operators = ['ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod', operators = ['ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod',
'all', 'size', 'exists'] 'all', 'size', 'exists', 'near']
match_operators = ['contains', 'icontains', 'startswith', match_operators = ['contains', 'icontains', 'startswith',
'istartswith', 'endswith', 'iendswith'] 'istartswith', 'endswith', 'iendswith']