Merge pull request #635 from SergeChmelev/master

Fix for post_init signal to receive correct state of _created flag.
This commit is contained in:
Omer Katz 2014-07-03 02:38:52 +03:00
commit f5cf616c2f
2 changed files with 26 additions and 7 deletions

View File

@ -60,6 +60,8 @@ class BaseDocument(object):
else: else:
self._data = SemiStrictDict.create(allowed_keys=self._fields_ordered)() self._data = SemiStrictDict.create(allowed_keys=self._fields_ordered)()
_created = values.pop("_created", True)
self._data = {}
self._dynamic_fields = SON() self._dynamic_fields = SON()
# Assign default values to instance # Assign default values to instance
@ -102,6 +104,7 @@ class BaseDocument(object):
# Flag initialised # Flag initialised
self._initialised = True self._initialised = True
self._created = _created
signals.post_init.send(self.__class__, document=self) signals.post_init.send(self.__class__, document=self)
def __delattr__(self, *args, **kwargs): def __delattr__(self, *args, **kwargs):
@ -619,9 +622,8 @@ class BaseDocument(object):
if cls.STRICT: if cls.STRICT:
data = dict((k, v) for k,v in data.iteritems() if k in cls._fields) data = dict((k, v) for k,v in data.iteritems() if k in cls._fields)
obj = cls(__auto_convert=False, **data) obj = cls(__auto_convert=False, _created=False, **data)
obj._changed_fields = changed_fields obj._changed_fields = changed_fields
obj._created = False
if not _auto_dereference: if not _auto_dereference:
obj._fields = fields obj._fields = fields
return obj return obj

View File

@ -37,7 +37,8 @@ class SignalTests(unittest.TestCase):
@classmethod @classmethod
def post_init(cls, sender, document, **kwargs): def post_init(cls, sender, document, **kwargs):
signal_output.append('post_init signal, %s' % document) signal_output.append('post_init signal, %s, document._created = %s' % (document, document._created))
@classmethod @classmethod
def pre_save(cls, sender, document, **kwargs): def pre_save(cls, sender, document, **kwargs):
@ -193,10 +194,16 @@ class SignalTests(unittest.TestCase):
a1 = self.Author(name='Bill Shakespeare') a1 = self.Author(name='Bill Shakespeare')
self.Author.objects.insert([a1], load_bulk=False) self.Author.objects.insert([a1], load_bulk=False)
def load_existing_author():
a = self.Author(name='Bill Shakespeare')
a.save()
self.get_signal_output(lambda: None) # eliminate signal output
a1 = self.Author.objects(name='Bill Shakespeare')[0]
self.assertEqual(self.get_signal_output(create_author), [ self.assertEqual(self.get_signal_output(create_author), [
"pre_init signal, Author", "pre_init signal, Author",
"{'name': 'Bill Shakespeare'}", "{'name': 'Bill Shakespeare'}",
"post_init signal, Bill Shakespeare", "post_init signal, Bill Shakespeare, document._created = True",
]) ])
a1 = self.Author(name='Bill Shakespeare') a1 = self.Author(name='Bill Shakespeare')
@ -225,12 +232,22 @@ class SignalTests(unittest.TestCase):
'post_delete signal, William Shakespeare', 'post_delete signal, William Shakespeare',
]) ])
signal_output = self.get_signal_output(load_existing_author)
# test signal_output lines separately, because of random ObjectID after object load
self.assertEqual(signal_output[0],
"pre_init signal, Author",
)
self.assertEqual(signal_output[2],
"post_init signal, Bill Shakespeare, document._created = False",
)
signal_output = self.get_signal_output(bulk_create_author_with_load) signal_output = self.get_signal_output(bulk_create_author_with_load)
# The output of this signal is not entirely deterministic. The reloaded # The output of this signal is not entirely deterministic. The reloaded
# object will have an object ID. Hence, we only check part of the output # object will have an object ID. Hence, we only check part of the output
self.assertEqual(signal_output[3], self.assertEqual(signal_output[3], "pre_bulk_insert signal, [<Author: Bill Shakespeare>]"
"pre_bulk_insert signal, [<Author: Bill Shakespeare>]") )
self.assertEqual(signal_output[-2:], self.assertEqual(signal_output[-2:],
["post_bulk_insert signal, [<Author: Bill Shakespeare>]", ["post_bulk_insert signal, [<Author: Bill Shakespeare>]",
"Is loaded",]) "Is loaded",])
@ -238,7 +255,7 @@ class SignalTests(unittest.TestCase):
self.assertEqual(self.get_signal_output(bulk_create_author_without_load), [ self.assertEqual(self.get_signal_output(bulk_create_author_without_load), [
"pre_init signal, Author", "pre_init signal, Author",
"{'name': 'Bill Shakespeare'}", "{'name': 'Bill Shakespeare'}",
"post_init signal, Bill Shakespeare", "post_init signal, Bill Shakespeare, document._created = True",
"pre_bulk_insert signal, [<Author: Bill Shakespeare>]", "pre_bulk_insert signal, [<Author: Bill Shakespeare>]",
"post_bulk_insert signal, [<Author: Bill Shakespeare>]", "post_bulk_insert signal, [<Author: Bill Shakespeare>]",
"Not loaded", "Not loaded",