new save() method updates only dirty fields. fixes issue #18

This commit is contained in:
Florian Schlachter
2010-01-31 14:40:00 +01:00
parent 7d6e117f68
commit 431f006751
4 changed files with 36 additions and 8 deletions

View File

@@ -1,8 +1,9 @@
from base import (DocumentMetaclass, TopLevelDocumentMetaclass, BaseDocument,
ValidationError)
from queryset import OperationError
from queryset import OperationError, QuerySet
from connection import _get_db
import pymongo
@@ -75,12 +76,30 @@ class Document(BaseDocument):
if force_insert:
object_id = collection.insert(doc, safe=safe)
else:
object_id = collection.save(doc, safe=safe)
if getattr(self, 'id', None) == None:
# new document
object_id = collection.save(doc, safe=safe)
else:
# update document
modified_fields = map(lambda obj: obj[0], filter(lambda obj: obj[1].modified, self._fields.items()))
modified_doc = dict(filter(lambda k: k[0] in modified_fields, doc.items()))
try:
id_field = self._meta['id_field']
idObj = self._fields[id_field].to_mongo(self['id'])
collection.update({'_id': idObj}, {'$set': modified_doc}, safe=safe)
except pymongo.errors.OperationFailure, err:
if str(err) == 'multi not coded yet':
raise OperationError('update() method requires MongoDB 1.1.3+')
raise OperationError('Update failed (%s)' % str(err))
object_id = self['id']
for field in self._fields.values(): field.modified = False
except pymongo.errors.OperationFailure, err:
message = 'Could not save document (%s)'
if 'duplicate key' in str(err):
message = 'Tried to save duplicate unique keys (%s)'
raise OperationError(message % str(err))
id_field = self._meta['id_field']
self[id_field] = self._fields[id_field].to_python(object_id)
@@ -106,6 +125,7 @@ class Document(BaseDocument):
obj = self.__class__.objects(**{id_field: self[id_field]}).first()
for field in self._fields:
setattr(self, field, obj[field])
obj.modified = False
@classmethod
def drop_collection(cls):