Added lock when calling doc.Delete() for when signals have no sender (#350)
This commit is contained in:
parent
d47134bbf1
commit
eeb5a83e98
@ -5,6 +5,7 @@ Changelog
|
|||||||
|
|
||||||
Changes in 0.8.2
|
Changes in 0.8.2
|
||||||
================
|
================
|
||||||
|
- Added lock when calling doc.Delete() for when signals have no sender (#350)
|
||||||
- Reload forces read preference to be PRIMARY (#355)
|
- Reload forces read preference to be PRIMARY (#355)
|
||||||
- Querysets are now lest restrictive when querying duplicate fields (#332, #333)
|
- Querysets are now lest restrictive when querying duplicate fields (#332, #333)
|
||||||
- FileField now honouring db_alias (#341)
|
- FileField now honouring db_alias (#341)
|
||||||
|
@ -347,11 +347,10 @@ class Document(BaseDocument):
|
|||||||
signals.pre_delete.send(self.__class__, document=self)
|
signals.pre_delete.send(self.__class__, document=self)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._qs.filter(**self._object_key).delete(write_concern=write_concern)
|
self._qs.filter(**self._object_key).delete(write_concern=write_concern, _from_doc_delete=True)
|
||||||
except pymongo.errors.OperationFailure, err:
|
except pymongo.errors.OperationFailure, err:
|
||||||
message = u'Could not delete document (%s)' % err.message
|
message = u'Could not delete document (%s)' % err.message
|
||||||
raise OperationError(message)
|
raise OperationError(message)
|
||||||
|
|
||||||
signals.post_delete.send(self.__class__, document=self)
|
signals.post_delete.send(self.__class__, document=self)
|
||||||
|
|
||||||
def switch_db(self, db_alias):
|
def switch_db(self, db_alias):
|
||||||
|
@ -407,7 +407,7 @@ class QuerySet(object):
|
|||||||
self._len = count
|
self._len = count
|
||||||
return count
|
return count
|
||||||
|
|
||||||
def delete(self, write_concern=None):
|
def delete(self, write_concern=None, _from_doc_delete=False):
|
||||||
"""Delete the documents matched by the query.
|
"""Delete the documents matched by the query.
|
||||||
|
|
||||||
:param write_concern: Extra keyword arguments are passed down which
|
:param write_concern: Extra keyword arguments are passed down which
|
||||||
@ -416,20 +416,25 @@ class QuerySet(object):
|
|||||||
``save(..., write_concern={w: 2, fsync: True}, ...)`` will
|
``save(..., write_concern={w: 2, fsync: True}, ...)`` will
|
||||||
wait until at least two servers have recorded the write and
|
wait until at least two servers have recorded the write and
|
||||||
will force an fsync on the primary server.
|
will force an fsync on the primary server.
|
||||||
|
:param _from_doc_delete: True when called from document delete therefore
|
||||||
|
signals will have been triggered so don't loop.
|
||||||
"""
|
"""
|
||||||
queryset = self.clone()
|
queryset = self.clone()
|
||||||
doc = queryset._document
|
doc = queryset._document
|
||||||
|
|
||||||
|
if not write_concern:
|
||||||
|
write_concern = {}
|
||||||
|
|
||||||
|
# Handle deletes where skips or limits have been applied or
|
||||||
|
# there is an untriggered delete signal
|
||||||
has_delete_signal = signals.signals_available and (
|
has_delete_signal = signals.signals_available and (
|
||||||
signals.pre_delete.has_receivers_for(self._document) or
|
signals.pre_delete.has_receivers_for(self._document) or
|
||||||
signals.post_delete.has_receivers_for(self._document))
|
signals.post_delete.has_receivers_for(self._document))
|
||||||
|
|
||||||
if not write_concern:
|
call_document_delete = (queryset._skip or queryset._limit or
|
||||||
write_concern = {}
|
has_delete_signal) and not _from_doc_delete
|
||||||
|
|
||||||
# Handle deletes where skips or limits have been applied or has a
|
if call_document_delete:
|
||||||
# delete signal
|
|
||||||
if queryset._skip or queryset._limit or has_delete_signal:
|
|
||||||
for doc in queryset:
|
for doc in queryset:
|
||||||
doc.delete(write_concern=write_concern)
|
doc.delete(write_concern=write_concern)
|
||||||
return
|
return
|
||||||
|
@ -41,7 +41,7 @@ class SignalTests(unittest.TestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def pre_save(cls, sender, document, **kwargs):
|
def pre_save(cls, sender, document, **kwargs):
|
||||||
signal_output.append('pre_save signal,, %s' % document)
|
signal_output.append('pre_save signal, %s' % document)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def pre_save_post_validation(cls, sender, document, **kwargs):
|
def pre_save_post_validation(cls, sender, document, **kwargs):
|
||||||
@ -83,54 +83,6 @@ class SignalTests(unittest.TestCase):
|
|||||||
self.Author = Author
|
self.Author = Author
|
||||||
Author.drop_collection()
|
Author.drop_collection()
|
||||||
|
|
||||||
class Another(Document):
|
|
||||||
name = StringField()
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def pre_init(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('pre_init Another signal, %s' % cls.__name__)
|
|
||||||
signal_output.append(str(kwargs['values']))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def post_init(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('post_init Another signal, %s' % document)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def pre_save(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('pre_save Another signal, %s' % document)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def pre_save_post_validation(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('pre_save_post_validation Another signal, %s' % document)
|
|
||||||
if 'created' in kwargs:
|
|
||||||
if kwargs['created']:
|
|
||||||
signal_output.append('Is created')
|
|
||||||
else:
|
|
||||||
signal_output.append('Is updated')
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def post_save(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('post_save Another signal, %s' % document)
|
|
||||||
if 'created' in kwargs:
|
|
||||||
if kwargs['created']:
|
|
||||||
signal_output.append('Is created')
|
|
||||||
else:
|
|
||||||
signal_output.append('Is updated')
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def pre_delete(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('pre_delete Another signal, %s' % document)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def post_delete(cls, sender, document, **kwargs):
|
|
||||||
signal_output.append('post_delete Another signal, %s' % document)
|
|
||||||
|
|
||||||
self.Another = Another
|
|
||||||
Another.drop_collection()
|
|
||||||
|
|
||||||
class ExplicitId(Document):
|
class ExplicitId(Document):
|
||||||
id = IntField(primary_key=True)
|
id = IntField(primary_key=True)
|
||||||
|
|
||||||
@ -169,14 +121,6 @@ class SignalTests(unittest.TestCase):
|
|||||||
signals.pre_bulk_insert.connect(Author.pre_bulk_insert, sender=Author)
|
signals.pre_bulk_insert.connect(Author.pre_bulk_insert, sender=Author)
|
||||||
signals.post_bulk_insert.connect(Author.post_bulk_insert, sender=Author)
|
signals.post_bulk_insert.connect(Author.post_bulk_insert, sender=Author)
|
||||||
|
|
||||||
signals.pre_init.connect(Another.pre_init, sender=Another)
|
|
||||||
signals.post_init.connect(Another.post_init, sender=Another)
|
|
||||||
signals.pre_save.connect(Another.pre_save, sender=Another)
|
|
||||||
signals.pre_save_post_validation.connect(Another.pre_save_post_validation, sender=Another)
|
|
||||||
signals.post_save.connect(Another.post_save, sender=Another)
|
|
||||||
signals.pre_delete.connect(Another.pre_delete, sender=Another)
|
|
||||||
signals.post_delete.connect(Another.post_delete, sender=Another)
|
|
||||||
|
|
||||||
signals.post_save.connect(ExplicitId.post_save, sender=ExplicitId)
|
signals.post_save.connect(ExplicitId.post_save, sender=ExplicitId)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
@ -190,14 +134,6 @@ class SignalTests(unittest.TestCase):
|
|||||||
signals.pre_bulk_insert.disconnect(self.Author.pre_bulk_insert)
|
signals.pre_bulk_insert.disconnect(self.Author.pre_bulk_insert)
|
||||||
signals.post_bulk_insert.disconnect(self.Author.post_bulk_insert)
|
signals.post_bulk_insert.disconnect(self.Author.post_bulk_insert)
|
||||||
|
|
||||||
signals.pre_init.disconnect(self.Another.pre_init)
|
|
||||||
signals.post_init.disconnect(self.Another.post_init)
|
|
||||||
signals.post_delete.disconnect(self.Another.post_delete)
|
|
||||||
signals.pre_delete.disconnect(self.Another.pre_delete)
|
|
||||||
signals.post_save.disconnect(self.Another.post_save)
|
|
||||||
signals.pre_save_post_validation.disconnect(self.Another.pre_save_post_validation)
|
|
||||||
signals.pre_save.disconnect(self.Another.pre_save)
|
|
||||||
|
|
||||||
signals.post_save.disconnect(self.ExplicitId.post_save)
|
signals.post_save.disconnect(self.ExplicitId.post_save)
|
||||||
|
|
||||||
# Check that all our signals got disconnected properly.
|
# Check that all our signals got disconnected properly.
|
||||||
@ -239,7 +175,7 @@ class SignalTests(unittest.TestCase):
|
|||||||
|
|
||||||
a1 = self.Author(name='Bill Shakespeare')
|
a1 = self.Author(name='Bill Shakespeare')
|
||||||
self.assertEqual(self.get_signal_output(a1.save), [
|
self.assertEqual(self.get_signal_output(a1.save), [
|
||||||
"pre_save signal,, Bill Shakespeare",
|
"pre_save signal, Bill Shakespeare",
|
||||||
"pre_save_post_validation signal, Bill Shakespeare",
|
"pre_save_post_validation signal, Bill Shakespeare",
|
||||||
"Is created",
|
"Is created",
|
||||||
"post_save signal, Bill Shakespeare",
|
"post_save signal, Bill Shakespeare",
|
||||||
@ -249,7 +185,7 @@ class SignalTests(unittest.TestCase):
|
|||||||
a1.reload()
|
a1.reload()
|
||||||
a1.name = 'William Shakespeare'
|
a1.name = 'William Shakespeare'
|
||||||
self.assertEqual(self.get_signal_output(a1.save), [
|
self.assertEqual(self.get_signal_output(a1.save), [
|
||||||
"pre_save signal,, William Shakespeare",
|
"pre_save signal, William Shakespeare",
|
||||||
"pre_save_post_validation signal, William Shakespeare",
|
"pre_save_post_validation signal, William Shakespeare",
|
||||||
"Is updated",
|
"Is updated",
|
||||||
"post_save signal, William Shakespeare",
|
"post_save signal, William Shakespeare",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user