我正在使用ndb.polymodel.PolyModel
为不同类型的社交媒体帐户建模。删除帐户后,必须进行一些清理(取决于子类)。
我尝试在子类上实现_pre_delete_hook
,但它永远不会被执行。将完全相同的钩子添加到其父类时,会执行:
class Account(polymodel.PolyModel):
user = ndb.KeyProperty(kind=User)
@classmethod
def _pre_delete_hook(cls, key):
# Works as expected
pass
class TwitterAccount(Account):
twitter_profile = ndb.StringProperty()
@classmethod
def _pre_delete_hook(cls, key):
# Never gets called
pass
t_account = TwitterAccount.get_by_id(1)
t_account.key.delete()
对我来说似乎很奇怪,因为我希望子类钩子覆盖它的父级。或者这是预期的行为?
解决方案:
我错过了在delete
(不是模型实例)上发生Key
操作的事实。密钥本身只知道最顶层的类的名称(在这种情况下为Account
)。
我最终在子类上定义了一个自定义_delete_hook
实例方法。当_pre_delete_hook
被调用时,我获取实体,然后检查它的类是否有一个特定的delete_hook来执行:
# In subclass:
def _delete_hook(self):
# Do stuff specific for this subclass
return
# In parent class
@classmethod
def _pre_delete_hook(cls, key):
s = key.get()
if hasattr(s, '_delete_hook'):
s._delete_hook()
答案 0 :(得分:0)
不幸的是,这是预期的非显而易见的行为
当您使用key
拨打PolyModel
删除时,您只在父类上调用删除。
看看你正在调用删除键,你会看到Kind是父模型。然后它通过Kind - >查找班级。类地图,它将为您提供Account
课程。阅读PolyModel的工作原理。它将所有Account子类存储为Account,并具有描述继承heirarchy的额外属性。因此,对Account的查询将返回所有Account子类,但TwitterAccount上的查询将仅返回该子类。
调用ndb.delete_multi也不起作用。
如果你想要一个特定的PolyModel子类pre delete hook来运行,你必须在子类中添加一个delete方法,然后调用它,然后可以调用子类_pre_delete_hook(并且可以调用super)。
但如果您直接致电key.delete