Promoted BaseDynamicField to DynamicField

closes mongoengine/mongoengine#22
This commit is contained in:
Ross Lawley 2012-05-17 21:54:17 +01:00
parent 376b9b1316
commit 8840680303
5 changed files with 52 additions and 46 deletions

View File

@ -2,6 +2,10 @@
Changelog Changelog
========= =========
Changes in 0.6.x
================
- Promoted BaseDynamicField to DynamicField
Changes in 0.6.9 Changes in 0.6.9
================ ================
- Fixed sparse indexes on inherited docs - Fixed sparse indexes on inherited docs

View File

@ -435,47 +435,6 @@ class ComplexBaseField(BaseField):
owner_document = property(_get_owner_document, _set_owner_document) owner_document = property(_get_owner_document, _set_owner_document)
class BaseDynamicField(BaseField):
"""Used by :class:`~mongoengine.DynamicDocument` to handle dynamic data"""
def to_mongo(self, value):
"""Convert a Python type to a MongoDBcompatible type.
"""
if isinstance(value, basestring):
return value
if hasattr(value, 'to_mongo'):
return value.to_mongo()
if not isinstance(value, (dict, list, tuple)):
return value
is_list = False
if not hasattr(value, 'items'):
is_list = True
value = dict([(k, v) for k, v in enumerate(value)])
data = {}
for k, v in value.items():
data[k] = self.to_mongo(v)
if is_list: # Convert back to a list
value = [v for k, v in sorted(data.items(), key=operator.itemgetter(0))]
else:
value = data
return value
def lookup_member(self, member_name):
return member_name
def prepare_query_value(self, op, value):
if isinstance(value, basestring):
from mongoengine.fields import StringField
return StringField().prepare_query_value(op, value)
return self.to_mongo(value)
class ObjectIdField(BaseField): class ObjectIdField(BaseField):
"""An field wrapper around MongoDB's ObjectIds. """An field wrapper around MongoDB's ObjectIds.
""" """
@ -859,7 +818,8 @@ class BaseDocument(object):
field = None field = None
if not hasattr(self, name) and not name.startswith('_'): if not hasattr(self, name) and not name.startswith('_'):
field = BaseDynamicField(db_field=name) from fields import DynamicField
field = DynamicField(db_field=name)
field.name = name field.name = name
self._dynamic_fields[name] = field self._dynamic_fields[name] = field

View File

@ -1,4 +1,5 @@
import pymongo import pymongo
from bson.dbref import DBRef from bson.dbref import DBRef
from mongoengine import signals from mongoengine import signals
@ -359,7 +360,7 @@ class DynamicDocument(Document):
way as an ordinary document but has expando style properties. Any data way as an ordinary document but has expando style properties. Any data
passed or set against the :class:`~mongoengine.DynamicDocument` that is passed or set against the :class:`~mongoengine.DynamicDocument` that is
not a field is automatically converted into a not a field is automatically converted into a
:class:`~mongoengine.BaseDynamicField` and data can be attributed to that :class:`~mongoengine.DynamicField` and data can be attributed to that
field. field.
..note:: ..note::

View File

@ -30,7 +30,7 @@ except ImportError:
__all__ = ['StringField', 'IntField', 'FloatField', 'BooleanField', __all__ = ['StringField', 'IntField', 'FloatField', 'BooleanField',
'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField', 'DateTimeField', 'EmbeddedDocumentField', 'ListField', 'DictField',
'ObjectIdField', 'ReferenceField', 'ValidationError', 'MapField', 'ObjectIdField', 'ReferenceField', 'ValidationError', 'MapField',
'DecimalField', 'ComplexDateTimeField', 'URLField', 'DecimalField', 'ComplexDateTimeField', 'URLField', 'DynamicField',
'GenericReferenceField', 'FileField', 'BinaryField', 'GenericReferenceField', 'FileField', 'BinaryField',
'SortedListField', 'EmailField', 'GeoPointField', 'ImageField', 'SortedListField', 'EmailField', 'GeoPointField', 'ImageField',
'SequenceField', 'UUIDField', 'GenericEmbeddedDocumentField'] 'SequenceField', 'UUIDField', 'GenericEmbeddedDocumentField']
@ -473,6 +473,47 @@ class GenericEmbeddedDocumentField(BaseField):
return data return data
class DynamicField(BaseField):
"""Used by :class:`~mongoengine.DynamicDocument` to handle dynamic data"""
def to_mongo(self, value):
"""Convert a Python type to a MongoDBcompatible type.
"""
if isinstance(value, basestring):
return value
if hasattr(value, 'to_mongo'):
return value.to_mongo()
if not isinstance(value, (dict, list, tuple)):
return value
is_list = False
if not hasattr(value, 'items'):
is_list = True
value = dict([(k, v) for k, v in enumerate(value)])
data = {}
for k, v in value.items():
data[k] = self.to_mongo(v)
if is_list: # Convert back to a list
value = [v for k, v in sorted(data.items(), key=itemgetter(0))]
else:
value = data
return value
def lookup_member(self, member_name):
return member_name
def prepare_query_value(self, op, value):
if isinstance(value, basestring):
from mongoengine.fields import StringField
return StringField().prepare_query_value(op, value)
return self.to_mongo(value)
class ListField(ComplexBaseField): class ListField(ComplexBaseField):
"""A list field that wraps a standard field, allowing multiple instances """A list field that wraps a standard field, allowing multiple instances
of the field to be used as a list in the database. of the field to be used as a list in the database.

View File

@ -627,8 +627,8 @@ class QuerySet(object):
if field_name in document._fields: if field_name in document._fields:
field = document._fields[field_name] field = document._fields[field_name]
elif document._dynamic: elif document._dynamic:
from base import BaseDynamicField from fields import DynamicField
field = BaseDynamicField(db_field=field_name) field = DynamicField(db_field=field_name)
else: else:
raise InvalidQueryError('Cannot resolve field "%s"' raise InvalidQueryError('Cannot resolve field "%s"'
% field_name) % field_name)