Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,4 @@ that much better:
* Paul-Armand Verhaegen (https://github.com/paularmand)
* Steven Rossiter (https://github.com/BeardedSteve)
* Luo Peng (https://github.com/RussellLuo)
* Bryan Bennett (https://github.com/bbenne10)
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Changes in 0.10.6
- Add support for mocking MongoEngine based on mongomock. #1151
- Fixed not being able to run tests on Windows. #1153
- Allow creation of sparse compound indexes. #1114
- Fixed not being able to specify `use_db_field=False` on `ListField(EmbeddedDocumentField)` instances

Changes in 0.10.5
=================
Expand Down
21 changes: 9 additions & 12 deletions mongoengine/base/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,20 +325,17 @@ def to_mongo(self, use_db_field=True, fields=None):

if value is not None:

if isinstance(field, EmbeddedDocumentField):
if fields:
key = '%s.' % field_name
embedded_fields = [
i.replace(key, '') for i in fields
if i.startswith(key)]
if fields:
key = '%s.' % field_name
embedded_fields = [
i.replace(key, '') for i in fields
if i.startswith(key)]

else:
embedded_fields = []

value = field.to_mongo(value, use_db_field=use_db_field,
fields=embedded_fields)
else:
value = field.to_mongo(value)
embedded_fields = []

value = field.to_mongo(value, use_db_field=use_db_field,
fields=embedded_fields)

# Handle self generating fields
if value is None and field._auto_gen:
Expand Down
22 changes: 12 additions & 10 deletions mongoengine/base/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def to_python(self, value):
"""
return value

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
"""Convert a Python type to a MongoDB-compatible type.
"""
return self.to_python(value)
Expand Down Expand Up @@ -325,7 +325,7 @@ def to_python(self, value):
key=operator.itemgetter(0))]
return value_dict

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
"""Convert a Python type to a MongoDB-compatible type.
"""
Document = _import_class("Document")
Expand All @@ -337,9 +337,10 @@ def to_mongo(self, value):

if hasattr(value, 'to_mongo'):
if isinstance(value, Document):
return GenericReferenceField().to_mongo(value)
return GenericReferenceField().to_mongo(
value, **kwargs)
cls = value.__class__
val = value.to_mongo()
val = value.to_mongo(**kwargs)
# If it's a document that is not inherited add _cls
if isinstance(value, EmbeddedDocument):
val['_cls'] = cls.__name__
Expand All @@ -354,7 +355,7 @@ def to_mongo(self, value):
return value

if self.field:
value_dict = dict([(key, self.field.to_mongo(item))
value_dict = dict([(key, self.field.to_mongo(item, **kwargs))
for key, item in value.iteritems()])
else:
value_dict = {}
Expand All @@ -373,19 +374,20 @@ def to_mongo(self, value):
meta.get('allow_inheritance', ALLOW_INHERITANCE)
is True)
if not allow_inheritance and not self.field:
value_dict[k] = GenericReferenceField().to_mongo(v)
value_dict[k] = GenericReferenceField().to_mongo(
v, **kwargs)
else:
collection = v._get_collection_name()
value_dict[k] = DBRef(collection, v.pk)
elif hasattr(v, 'to_mongo'):
cls = v.__class__
val = v.to_mongo()
val = v.to_mongo(**kwargs)
# If it's a document that is not inherited add _cls
if isinstance(v, (Document, EmbeddedDocument)):
val['_cls'] = cls.__name__
value_dict[k] = val
else:
value_dict[k] = self.to_mongo(v)
value_dict[k] = self.to_mongo(v, **kwargs)

if is_list: # Convert back to a list
return [v for _, v in sorted(value_dict.items(),
Expand Down Expand Up @@ -443,7 +445,7 @@ def to_python(self, value):
pass
return value

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
if not isinstance(value, ObjectId):
try:
return ObjectId(unicode(value))
Expand Down Expand Up @@ -618,7 +620,7 @@ def _validate_multipolygon(self, value):
if errors:
return "Invalid MultiPolygon:\n%s" % ", ".join(errors)

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
if isinstance(value, dict):
return value
return SON([("type", self._type), ("coordinates", value)])
46 changes: 23 additions & 23 deletions mongoengine/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def to_python(self, value):
return value
return value.quantize(decimal.Decimal(".%s" % ("0" * self.precision)), rounding=self.rounding)

def to_mongo(self, value, use_db_field=True):
def to_mongo(self, value, **kwargs):
if value is None:
return value
if self.force_string:
Expand Down Expand Up @@ -388,7 +388,7 @@ def validate(self, value):
if not isinstance(new_value, (datetime.datetime, datetime.date)):
self.error(u'cannot parse date "%s"' % value)

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
if value is None:
return value
if isinstance(value, datetime.datetime):
Expand Down Expand Up @@ -511,7 +511,7 @@ def to_python(self, value):
except:
return original_value

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
value = self.to_python(value)
return self._convert_from_datetime(value)

Expand Down Expand Up @@ -546,11 +546,10 @@ def to_python(self, value):
return self.document_type._from_son(value, _auto_dereference=self._auto_dereference)
return value

def to_mongo(self, value, use_db_field=True, fields=[]):
def to_mongo(self, value, **kwargs):
if not isinstance(value, self.document_type):
return value
return self.document_type.to_mongo(value, use_db_field,
fields=fields)
return self.document_type.to_mongo(value, **kwargs)

def validate(self, value, clean=True):
"""Make sure that the document instance is an instance of the
Expand Down Expand Up @@ -600,11 +599,11 @@ def validate(self, value, clean=True):

value.validate(clean=clean)

def to_mongo(self, document, use_db_field=True):
def to_mongo(self, document, **kwargs):
if document is None:
return None

data = document.to_mongo(use_db_field)
data = document.to_mongo(**kwargs)
if '_cls' not in data:
data['_cls'] = document._class_name
return data
Expand All @@ -616,7 +615,7 @@ class DynamicField(BaseField):

Used by :class:`~mongoengine.DynamicDocument` to handle dynamic data"""

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
"""Convert a Python type to a MongoDB compatible type.
"""

Expand All @@ -625,7 +624,7 @@ def to_mongo(self, value):

if hasattr(value, 'to_mongo'):
cls = value.__class__
val = value.to_mongo()
val = value.to_mongo(**kwargs)
# If we its a document thats not inherited add _cls
if isinstance(value, Document):
val = {"_ref": value.to_dbref(), "_cls": cls.__name__}
Expand All @@ -643,7 +642,7 @@ def to_mongo(self, value):

data = {}
for k, v in value.iteritems():
data[k] = self.to_mongo(v)
data[k] = self.to_mongo(v, **kwargs)

value = data
if is_list: # Convert back to a list
Expand Down Expand Up @@ -755,8 +754,8 @@ def __init__(self, field, **kwargs):
self._order_reverse = kwargs.pop('reverse')
super(SortedListField, self).__init__(field, **kwargs)

def to_mongo(self, value):
value = super(SortedListField, self).to_mongo(value)
def to_mongo(self, value, **kwargs):
value = super(SortedListField, self).to_mongo(value, **kwargs)
if self._ordering is not None:
return sorted(value, key=itemgetter(self._ordering),
reverse=self._order_reverse)
Expand Down Expand Up @@ -942,7 +941,7 @@ def __get__(self, instance, owner):

return super(ReferenceField, self).__get__(instance, owner)

def to_mongo(self, document):
def to_mongo(self, document, **kwargs):
if isinstance(document, DBRef):
if not self.dbref:
return document.id
Expand All @@ -965,7 +964,7 @@ def to_mongo(self, document):
id_field_name = cls._meta['id_field']
id_field = cls._fields[id_field_name]

id_ = id_field.to_mongo(id_)
id_ = id_field.to_mongo(id_, **kwargs)
if self.document_type._meta.get('abstract'):
collection = cls._get_collection_name()
return DBRef(collection, id_, cls=cls._class_name)
Expand Down Expand Up @@ -1088,7 +1087,7 @@ def __get__(self, instance, owner):

return super(CachedReferenceField, self).__get__(instance, owner)

def to_mongo(self, document):
def to_mongo(self, document, **kwargs):
id_field_name = self.document_type._meta['id_field']
id_field = self.document_type._fields[id_field_name]

Expand All @@ -1103,10 +1102,11 @@ def to_mongo(self, document):
# TODO: should raise here or will fail next statement

value = SON((
("_id", id_field.to_mongo(id_)),
("_id", id_field.to_mongo(id_, **kwargs)),
))

value.update(dict(document.to_mongo(fields=self.fields)))
kwargs['fields'] = self.fields
value.update(dict(document.to_mongo(**kwargs)))
return value

def prepare_query_value(self, op, value):
Expand Down Expand Up @@ -1222,7 +1222,7 @@ def dereference(self, value):
doc = doc_cls._from_son(doc)
return doc

def to_mongo(self, document, use_db_field=True):
def to_mongo(self, document, **kwargs):
if document is None:
return None

Expand All @@ -1241,7 +1241,7 @@ def to_mongo(self, document, use_db_field=True):
else:
id_ = document

id_ = id_field.to_mongo(id_)
id_ = id_field.to_mongo(id_, **kwargs)
collection = document._get_collection_name()
ref = DBRef(collection, id_)
return SON((
Expand Down Expand Up @@ -1270,7 +1270,7 @@ def __set__(self, instance, value):
value = bin_type(value)
return super(BinaryField, self).__set__(instance, value)

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
return Binary(value)

def validate(self, value):
Expand Down Expand Up @@ -1495,7 +1495,7 @@ def get_proxy_obj(self, key, instance, db_alias=None, collection_name=None):
db_alias=db_alias,
collection_name=collection_name)

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
# Store the GridFS file id in MongoDB
if isinstance(value, self.proxy_class) and value.grid_id is not None:
return value.grid_id
Expand Down Expand Up @@ -1845,7 +1845,7 @@ def to_python(self, value):
return original_value
return value

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
if not self._binary:
return unicode(value)
elif isinstance(value, basestring):
Expand Down
13 changes: 13 additions & 0 deletions tests/document/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,19 @@ class Doc(Document):
doc = Doc.objects.get()
self.assertHasInstance(doc.embedded_field[0], doc)

def test_embedded_document_complex_instance_no_use_db_field(self):
"""Ensure that use_db_field is propagated to list of Emb Docs
"""
class Embedded(EmbeddedDocument):
string = StringField(db_field='s')

class Doc(Document):
embedded_field = ListField(EmbeddedDocumentField(Embedded))

d = Doc(embedded_field=[Embedded(string="Hi")]).to_mongo(
use_db_field=False).to_dict()
self.assertEqual(d['embedded_field'], [{'string': 'Hi'}])

def test_instance_is_set_on_setattr(self):

class Email(EmbeddedDocument):
Expand Down
2 changes: 1 addition & 1 deletion tests/fields/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3380,7 +3380,7 @@ class EnumField(BaseField):
def __init__(self, **kwargs):
super(EnumField, self).__init__(**kwargs)

def to_mongo(self, value):
def to_mongo(self, value, **kwargs):
return value

def to_python(self, value):
Expand Down