Merge pull request #742 from bocribbz/dictfield-atomic-update

Allow atomic update for the entire `DictField`
This commit is contained in:
Yohan Graterol 2014-08-19 23:13:37 -05:00
commit b349a449bb
3 changed files with 30 additions and 0 deletions

View File

@ -206,3 +206,4 @@ that much better:
* Clay McClure (https://github.com/claymation)
* Bruno Rocha (https://github.com/rochacbruno)
* Norberto Leite (https://github.com/nleite)
* Bob Cribbs (https://github.com/bocribbz)

View File

@ -826,6 +826,10 @@ class DictField(ComplexBaseField):
return StringField().prepare_query_value(op, value)
if hasattr(self.field, 'field'):
if op in ('set', 'unset') and isinstance(value, dict):
return dict(
(k, self.field.prepare_query_value(op, v))
for k, v in value.items())
return self.field.prepare_query_value(op, value)
return super(DictField, self).prepare_query_value(op, value)

View File

@ -18,6 +18,7 @@ from bson import Binary, DBRef, ObjectId
from mongoengine import *
from mongoengine.connection import get_db
from mongoengine.base import _document_registry
from mongoengine.base.datastructures import BaseDict
from mongoengine.errors import NotRegistered
from mongoengine.python_support import PY3, b, bin_type
@ -1251,6 +1252,30 @@ class FieldTest(unittest.TestCase):
Simple.drop_collection()
def test_atomic_update_dict_field(self):
"""Ensure that the entire DictField can be atomically updated."""
class Simple(Document):
mapping = DictField(field=ListField(IntField(required=True)))
Simple.drop_collection()
e = Simple()
e.mapping['someints'] = [1, 2]
e.save()
e.update(set__mapping={"ints": [3, 4]})
e.reload()
self.assertEqual(BaseDict, type(e.mapping))
self.assertEqual({"ints": [3, 4]}, e.mapping)
def create_invalid_mapping():
e.update(set__mapping={"somestrings": ["foo", "bar",]})
self.assertRaises(ValueError, create_invalid_mapping)
Simple.drop_collection()
def test_mapfield(self):
"""Ensure that the MapField handles the declared type."""