Skip to content

Commit

Permalink
Merge remote branch 'wpjunior/genericembeddedfield' into genericembed…
Browse files Browse the repository at this point in the history
…dedfield
  • Loading branch information
rozza committed Sep 9, 2011
2 parents ee7d370 + 6471c6e commit 2bc3948
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
28 changes: 27 additions & 1 deletion mongoengine/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
'DecimalField', 'ComplexDateTimeField', 'URLField',
'GenericReferenceField', 'FileField', 'BinaryField',
'SortedListField', 'EmailField', 'GeoPointField',
'SequenceField']
'SequenceField', 'GenericEmbeddedDocumentField']

RECURSIVE_REFERENCE_CONSTANT = 'self'

Expand Down Expand Up @@ -421,6 +421,32 @@ def lookup_member(self, member_name):
def prepare_query_value(self, op, value):
return self.to_mongo(value)

class GenericEmbeddedDocumentField(BaseField):
def prepare_query_value(self, op, value):
return self.to_mongo(value)

def to_python(self, value):
if isinstance(value, dict):
doc_cls = get_document(value['_cls'])
value = doc_cls._from_son(value)

return value

def validate(self, value):
if not isinstance(value, EmbeddedDocument):
raise ValidationError('Invalid embedded document instance '
'provided to an GenericEmbeddedDocumentField')

value.validate()

def to_mongo(self, document):
if document is None:
return None

data = document.to_mongo()
if not '_cls' in data:
data['_cls'] = document._class_name
return data

class ListField(ComplexBaseField):
"""A list field that wraps a standard field, allowing multiple instances
Expand Down
25 changes: 25 additions & 0 deletions tests/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1489,5 +1489,30 @@ class Person(Document):
self.assertEqual(c['next'], 10)


def test_generic_embedded_document(self):
class Car(EmbeddedDocument):
name = StringField()

class Dish(EmbeddedDocument):
food = StringField(required=True)
number = IntField()

class Person(Document):
name = StringField()
like = GenericEmbeddedDocumentField()

person = Person(name='Test User')
person.like = Car(name='Fiat')
person.save()

person = Person.objects.first()
self.assertTrue(isinstance(person.like, Car))

person.like = Dish(food="arroz", number=15)
person.save()

person = Person.objects.first()
self.assertTrue(isinstance(person.like, Dish))

if __name__ == '__main__':
unittest.main()

0 comments on commit 2bc3948

Please sign in to comment.