Merge pull request #697 from nleite/master

to_json not resolving db_fields #654
This commit is contained in:
Yohan Graterol 2014-07-07 17:39:34 -05:00
commit f6220cab3b
5 changed files with 52 additions and 19 deletions

View File

@ -205,3 +205,4 @@ that much better:
* Aleksandr Sorokoumov (https://github.com/Gerrrr)
* Clay McClure (https://github.com/claymation)
* Bruno Rocha (https://github.com/rochacbruno)
* Norberto Leite (https://github.com/nleite)

View File

@ -5,7 +5,7 @@ Changelog
Changes in 0.9.X - DEV
======================
- Added support to show original model fields on to_json calls instead of db_field #697
- Fixed tests for Django 1.7 #696
- Follow ReferenceFields in EmbeddedDocuments with select_related #690
- Added preliminary support for text indexes #680

View File

@ -257,7 +257,7 @@ class BaseDocument(object):
"""
pass
def to_mongo(self):
def to_mongo(self, use_db_field=True):
"""Return as SON data ready for use with MongoDB.
"""
data = SON()
@ -271,7 +271,11 @@ class BaseDocument(object):
field = self._dynamic_fields.get(field_name)
if value is not None:
value = field.to_mongo(value)
EmbeddedDocument = _import_class("EmbeddedDocument")
if isinstance(value, (EmbeddedDocument)) and use_db_field==False:
value = field.to_mongo(value, use_db_field)
else:
value = field.to_mongo(value)
# Handle self generating fields
if value is None and field._auto_gen:
@ -279,7 +283,10 @@ class BaseDocument(object):
self._data[field_name] = value
if value is not None:
data[field.db_field] = value
if use_db_field:
data[field.db_field] = value
else:
data[field.name] = value
# If "_id" has not been set, then try and set it
Document = _import_class("Document")
@ -342,8 +349,11 @@ class BaseDocument(object):
raise ValidationError(message, errors=errors)
def to_json(self, *args, **kwargs):
"""Converts a document to JSON"""
return json_util.dumps(self.to_mongo(), *args, **kwargs)
"""Converts a document to JSON.
:param use_db_field: Set to True by default but enables the output of the json structure with the field names and not the mongodb store db_names in case of set to False
"""
use_db_field = kwargs.pop('use_db_field') if kwargs.has_key('use_db_field') else True
return json_util.dumps(self.to_mongo(use_db_field), *args, **kwargs)
@classmethod
def from_json(cls, json_data):

View File

@ -311,7 +311,7 @@ class DecimalField(BaseField):
return value
return value.quantize(self.precision, rounding=self.rounding)
def to_mongo(self, value):
def to_mongo(self, value, use_db_field=True):
if value is None:
return value
if self.force_string:
@ -551,10 +551,10 @@ class EmbeddedDocumentField(BaseField):
return self.document_type._from_son(value)
return value
def to_mongo(self, value):
def to_mongo(self, value, use_db_field=True):
if not isinstance(value, self.document_type):
return value
return self.document_type.to_mongo(value)
return self.document_type.to_mongo(value, use_db_field)
def validate(self, value, clean=True):
"""Make sure that the document instance is an instance of the
@ -601,11 +601,11 @@ class GenericEmbeddedDocumentField(BaseField):
value.validate(clean=clean)
def to_mongo(self, document):
def to_mongo(self, document, use_db_field=True):
if document is None:
return None
data = document.to_mongo()
data = document.to_mongo(use_db_field)
if not '_cls' in data:
data['_cls'] = document._class_name
return data
@ -628,7 +628,7 @@ class DynamicField(BaseField):
cls = value.__class__
val = value.to_mongo()
# If we its a document thats not inherited add _cls
if (isinstance(value, Document)):
if (isinstance(value, Document)):
val = {"_ref": value.to_dbref(), "_cls": cls.__name__}
if (isinstance(value, EmbeddedDocument)):
val['_cls'] = cls.__name__
@ -1001,7 +1001,7 @@ class GenericReferenceField(BaseField):
doc = doc_cls._from_son(doc)
return doc
def to_mongo(self, document):
def to_mongo(self, document, use_db_field=True):
if document is None:
return None

View File

@ -20,6 +20,28 @@ class TestJson(unittest.TestCase):
def setUp(self):
connect(db='mongoenginetest')
def test_json_names(self):
"""
Going to test reported issue:
https://github.com/MongoEngine/mongoengine/issues/654
where the reporter asks for the availability to perform
a to_json with the original class names and not the abreviated
mongodb document keys
"""
class Embedded(EmbeddedDocument):
string = StringField(db_field='s')
class Doc(Document):
string = StringField(db_field='s')
embedded = EmbeddedDocumentField(Embedded, db_field='e')
doc = Doc( string="Hello", embedded=Embedded(string="Inner Hello"))
doc_json = doc.to_json(sort_keys=True, use_db_field=False,separators=(',', ':'))
expected_json = """{"embedded":{"string":"Inner Hello"},"string":"Hello"}"""
self.assertEqual( doc_json, expected_json)
def test_json_simple(self):
class Embedded(EmbeddedDocument):