Added initial implementation of cascading document deletion.
The current implementation is still very basic and needs some polish. The essence of it is that each Document gets a new meta attribute called "delete_rules" that is a dictionary containing (documentclass, fieldname) as key and the actual delete rule as a value. (Possible values are DO_NOTHING, NULLIFY, CASCADE and DENY. Of those, only CASCADE is currently implented.)
This commit is contained in:
@@ -6,9 +6,16 @@ from connection import _get_db
|
||||
import pymongo
|
||||
|
||||
|
||||
__all__ = ['Document', 'EmbeddedDocument', 'ValidationError', 'OperationError']
|
||||
__all__ = ['Document', 'EmbeddedDocument', 'ValidationError', 'OperationError',
|
||||
'DO_NOTHING', 'NULLIFY', 'CASCADE', 'DENY']
|
||||
|
||||
|
||||
# Delete rules
|
||||
DO_NOTHING = 0
|
||||
NULLIFY = 1
|
||||
CASCADE = 2
|
||||
DENY = 3
|
||||
|
||||
class EmbeddedDocument(BaseDocument):
|
||||
"""A :class:`~mongoengine.Document` that isn't stored in its own
|
||||
collection. :class:`~mongoengine.EmbeddedDocument`\ s should be used as
|
||||
@@ -92,6 +99,13 @@ class Document(BaseDocument):
|
||||
|
||||
:param safe: check if the operation succeeded before returning
|
||||
"""
|
||||
for rule_entry in self._meta['delete_rules']:
|
||||
document_cls, field_name = rule_entry
|
||||
rule = self._meta['delete_rules'][rule_entry]
|
||||
|
||||
if rule == CASCADE:
|
||||
document_cls.objects(**{field_name: self.id}).delete(safe=safe)
|
||||
|
||||
id_field = self._meta['id_field']
|
||||
object_id = self._fields[id_field].to_mongo(self[id_field])
|
||||
try:
|
||||
@@ -100,6 +114,17 @@ class Document(BaseDocument):
|
||||
message = u'Could not delete document (%s)' % err.message
|
||||
raise OperationError(message)
|
||||
|
||||
@classmethod
|
||||
def register_delete_rule(cls, document_cls, field_name, rule):
|
||||
"""This method registers the delete rules to apply when removing this
|
||||
object. This could go into the Document class.
|
||||
"""
|
||||
if rule == DO_NOTHING:
|
||||
return
|
||||
|
||||
cls._meta['delete_rules'][(document_cls, field_name)] = rule
|
||||
|
||||
|
||||
def reload(self):
|
||||
"""Reloads all attributes from the database.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user