refs #709, added support to disable auto_sync
This commit is contained in:
parent
15bbf26b93
commit
6c0112c2be
@ -182,6 +182,9 @@ class DocumentMetaclass(type):
|
||||
raise InvalidDocumentError(
|
||||
"Document is not avaiable to sync")
|
||||
|
||||
if f.auto_sync:
|
||||
f.start_listener()
|
||||
|
||||
f.document_type._cached_reference_fields.append(f)
|
||||
|
||||
if isinstance(f, ComplexBaseField) and hasattr(f, 'field'):
|
||||
|
@ -989,10 +989,11 @@ class CachedReferenceField(BaseField):
|
||||
.. versionadded:: 0.9
|
||||
"""
|
||||
|
||||
def __init__(self, document_type, fields=[], **kwargs):
|
||||
def __init__(self, document_type, fields=[], auto_sync=True, **kwargs):
|
||||
"""Initialises the Cached Reference Field.
|
||||
|
||||
:param fields: A list of fields to be cached in document
|
||||
:param auto_sync: if True documents are auto updated.
|
||||
"""
|
||||
if not isinstance(document_type, basestring) and \
|
||||
not issubclass(document_type, (Document, basestring)):
|
||||
@ -1000,10 +1001,33 @@ class CachedReferenceField(BaseField):
|
||||
self.error('Argument to CachedReferenceField constructor must be a'
|
||||
' document class or a string')
|
||||
|
||||
self.auto_sync = auto_sync
|
||||
self.document_type_obj = document_type
|
||||
self.fields = fields
|
||||
super(CachedReferenceField, self).__init__(**kwargs)
|
||||
|
||||
def start_listener(self):
|
||||
"""
|
||||
Start listener for document alterations, and update relacted docs
|
||||
"""
|
||||
from mongoengine import signals
|
||||
signals.post_save.connect(self.on_document_pre_save,
|
||||
sender=self.document_type)
|
||||
|
||||
def on_document_pre_save(self, sender, document, created, **kwargs):
|
||||
if not created:
|
||||
update_kwargs = {
|
||||
'set__%s__%s' % (self.name, k): v
|
||||
for k, v in document._delta()[0].items()
|
||||
if k in self.fields}
|
||||
|
||||
if update_kwargs:
|
||||
filter_kwargs = {}
|
||||
filter_kwargs[self.name] = document
|
||||
|
||||
self.owner_document.objects(
|
||||
**filter_kwargs).update(**update_kwargs)
|
||||
|
||||
def to_python(self, value):
|
||||
"""Convert a MongoDB-compatible type to a Python type.
|
||||
"""
|
||||
@ -1088,7 +1112,6 @@ class CachedReferenceField(BaseField):
|
||||
|
||||
def sync_all(self):
|
||||
update_key = 'set__%s' % self.name
|
||||
errors = []
|
||||
|
||||
for doc in self.document_type.objects:
|
||||
filter_kwargs = {}
|
||||
@ -1097,8 +1120,6 @@ class CachedReferenceField(BaseField):
|
||||
update_kwargs = {}
|
||||
update_kwargs[update_key] = doc
|
||||
|
||||
errors.append((filter_kwargs, update_kwargs))
|
||||
|
||||
self.owner_document.objects(
|
||||
**filter_kwargs).update(**update_kwargs)
|
||||
|
||||
|
@ -1608,6 +1608,76 @@ class FieldTest(unittest.TestCase):
|
||||
|
||||
self.assertRaises(InvalidDocumentError, build)
|
||||
|
||||
def test_cached_reference_auto_sync(self):
|
||||
class Person(Document):
|
||||
TYPES = (
|
||||
('pf', "PF"),
|
||||
('pj', "PJ")
|
||||
)
|
||||
name = StringField()
|
||||
tp = StringField(
|
||||
choices=TYPES
|
||||
)
|
||||
|
||||
father = CachedReferenceField('self', fields=('tp',))
|
||||
|
||||
Person.drop_collection()
|
||||
|
||||
a1 = Person(name="Wilson Father", tp="pj")
|
||||
a1.save()
|
||||
|
||||
a2 = Person(name='Wilson Junior', tp='pf', father=a1)
|
||||
a2.save()
|
||||
|
||||
a1.tp = 'pf'
|
||||
a1.save()
|
||||
|
||||
a2.reload()
|
||||
self.assertEqual(dict(a2.to_mongo()), {
|
||||
'_id': a2.pk,
|
||||
'name': 'Wilson Junior',
|
||||
'tp': 'pf',
|
||||
'father': {
|
||||
'_id': a1.pk,
|
||||
'tp': 'pf'
|
||||
}
|
||||
})
|
||||
|
||||
def test_cached_reference_auto_sync_disabled(self):
|
||||
class Persone(Document):
|
||||
TYPES = (
|
||||
('pf', "PF"),
|
||||
('pj', "PJ")
|
||||
)
|
||||
name = StringField()
|
||||
tp = StringField(
|
||||
choices=TYPES
|
||||
)
|
||||
|
||||
father = CachedReferenceField(
|
||||
'self', fields=('tp',), auto_sync=False)
|
||||
|
||||
Persone.drop_collection()
|
||||
|
||||
a1 = Persone(name="Wilson Father", tp="pj")
|
||||
a1.save()
|
||||
|
||||
a2 = Persone(name='Wilson Junior', tp='pf', father=a1)
|
||||
a2.save()
|
||||
|
||||
a1.tp = 'pf'
|
||||
a1.save()
|
||||
|
||||
self.assertEqual(Persone.objects._collection.find_one({'_id': a2.pk}), {
|
||||
'_id': a2.pk,
|
||||
'name': 'Wilson Junior',
|
||||
'tp': 'pf',
|
||||
'father': {
|
||||
'_id': a1.pk,
|
||||
'tp': 'pj'
|
||||
}
|
||||
})
|
||||
|
||||
def test_cached_reference_embedded_fields(self):
|
||||
class Owner(EmbeddedDocument):
|
||||
TPS = (
|
||||
|
Loading…
x
Reference in New Issue
Block a user