我有两个文档对象(Job
和JobLog
),一个引用另一个(JobLog有对Job的引用字段)。并且引用是用reverse_delete_rule=CASCADE
定义的。
# Job class
class Job(db.Document):
(fields)
class JobLog(db.Document):
(fields)
job = ReferenceField(Job, required=True, reverse_delete_rule=CASCADE)
当我删除Job
对象并引用时,JobLog
安全删除。
>>> job = Job()
>>> job.save()
>>> job_log = JobLog()
>>> job_log = job
>>> job_log.save()
>>> job.delete()
>>> JobLog.objects().all()
[]
过了一会儿,我像这样覆盖JobLog
delete
方法:
class JobLog(db.Document):
(fields)
job = ReferenceField(Job, required=True, reverse_delete_rule=CASCADE)
def delete(self, signal_kwargs=None, **write_concern):
(some operations)
print("Delete method called.")
super(JobLog, self).delete(signal_kwargs, **write_concern)
但是在删除时,Job
覆盖的删除方法没有调用。
>>> job = Job()
>>> job.save()
>>> job_log = JobLog()
>>> job_log = job
>>> job_log.save()
>>> job.delete()
>>> JobLog.objects().all()
[]
引用JobLog
删除,但未调用重写的 delete
方法。
我最终得到了一个解决方案,如果有人遇到这种问题,我将分享它。
我不知道为什么不调用覆盖的delete
方法的每个细节,但似乎基Document
类将继承的类视为Document
类并称其为超类方法。因此未调用重写的删除方法。
解决方案是使用信号来确保在删除和保存等方法之前或之后处理操作。这个片段对我有用:
class JobLog(db.Document):
@classmethod
def pre_delete(cls, sender, document, **kwargs):
(pre delete operations)
from mongoengine import signals
signals.pre_delete.connect(JobLog.pre_delete, sender=JobLog)
信号支持由闪光灯库提供。确保在使用 mongoengine 信号之前安装。