Added support for pull operations on nested EmbeddedDocs

fixes mongoengine/mongoengine#16
This commit is contained in:
Ross Lawley 2012-05-09 14:38:53 +01:00
parent bbefd0fdf9
commit a536097804
3 changed files with 42 additions and 3 deletions

View File

@ -4,6 +4,7 @@ Changelog
Changes in 0.6.X
================
- Added support for pull operations on nested EmbeddedDocuments
- Added support for choices with GenericReferenceFields
- Added support for choices with GenericEmbeddedDocumentFields
- Fixed Django 1.4 sessions first save data loss

View File

@ -1380,9 +1380,18 @@ class QuerySet(object):
if not op:
raise InvalidQueryError("Updates must supply an operation eg: set__FIELD=value")
if op:
if 'pull' in op and '.' in key:
# Dot operators don't work on pull operations
# it uses nested dict syntax
if op == 'pullAll':
raise InvalidQueryError("pullAll operations only support a single field depth")
parts.reverse()
for key in parts:
value = {key: value}
else:
value = {key: value}
key = '$' + op
key = '$' + op
if key not in mongo_update:
mongo_update[key] = value

View File

@ -572,7 +572,7 @@ class QuerySetTest(unittest.TestCase):
def throw_operation_error_not_unique():
Blog.objects.insert([blog2, blog3], safe=True)
self.assertRaises(OperationError, throw_operation_error_not_unique)
self.assertEqual(Blog.objects.count(), 2)
@ -1471,6 +1471,35 @@ class QuerySetTest(unittest.TestCase):
post.reload()
self.assertEqual(post.tags, ["code", "mongodb"])
def test_pull_nested(self):
class User(Document):
name = StringField()
class Collaborator(EmbeddedDocument):
user = StringField()
def __unicode__(self):
return '%s' % self.user
class Site(Document):
name = StringField(max_length=75, unique=True, required=True)
collaborators = ListField(EmbeddedDocumentField(Collaborator))
Site.drop_collection()
c = Collaborator(user='Esteban')
s = Site(name="test", collaborators=[c])
s.save()
Site.objects(id=s.id).update_one(pull__collaborators__user='Esteban')
self.assertEqual(Site.objects.first().collaborators, [])
def pull_all():
Site.objects(id=s.id).update_one(pull_all__collaborators__user=['Ross'])
self.assertRaises(InvalidQueryError, pull_all)
def test_update_one_pop_generic_reference(self):