挂钩是在现有代码之前,之后或代替现有代码执行的函数。在odoo中,挂钩是在模块的__init__.py
内部定义的函数的字符串表示形式。
简单理解
就像一些外来的钩子,在源代码之间钩取一些信息,当捕捉到感兴趣的事时,就拦截下来,让自己的代码执行一下,处理一下这个信息,然后再放出去继续之前的进程。
这样就可以在不用改变源代码的情况下,做一些别的事情,比方说监控、分析和一些恶意的事
- 引用知乎上著名的示意图
在odoo挂钩中,以下类型的挂钩:
-
pre_init_hook
-
post_init_hook
-
uninstall_hook
-
post_load
挂钩是使用上述关键字在模块内部的__manifest__.py文件中定义的,如下所示。
{
'pre_init_hook':'test_pre_init_hook',
'post_init_hook':'test_post_init_hook',
'uninstall_hook':'test_uninstall_hook',
'post_load':'test_post_load',
}
挂钩键之后的清单的值位置中的字符串是在__init__.py
文件中定义的函数名称。
根据OCA指南,挂钩函数应放置在hooks.py
文件中,该文件位于模块目录的根目录下。还记得添加到__init__.py
文件并按以下方式导入,
从
.hooks
导入pre_init_hook
,post_init_hook
,uninstall_hook
,post_load
如果您遵循OCA使用钩子的准则,则模块结构如下所示,
让我们检查一下如何编写钩子,以及每个钩子在odoo开发中钩子的详细用法。
预初始化钩
预初始化挂钩是在模块安装之前执行的挂钩函数。如果我们在模块内部定义了pre_init_hook
,则只要用户单击该模块的安装按钮,钩子函数就会执行。在安装模块之前,将调用pre_init_hook
函数并执行一些操作。
pre_init_hook
将游标作为唯一参数,例如,您可以按以下方式定义pre_init_function
。
您可以如下定义pre_init_function
。
首先,您需要编写清单文件,如下所示:
然后,您必须在模块内部的ooks.py文件中以及__init__.py中编写函数定义,如下所示
在hooks.py文件中,定义清单中提供的名称的pre_init_hook函数,
在将模块的逻辑注册到他们的模块。模块中之前,可以使用此挂钩。Pre_init_hook通常用于检查模块的兼容性。通过使用pre_init_hook,我们可以在数据库中进行一些修改,以便为模块安装做准备。
开机自检钩
这些是在模块安装后立即执行的功能。post_init_hook
函数的参数是数据库游标和注册表。
您可以如下定义post_init_function
。
在清单文件中
在您的__init__.py
文件中导入post_init_hook
函数,并如下定义函数。
在 hooks.py
文件中,如下定义函数,
您可以使用post_init_function在数据库内部执行一些操作,以完成模块安装。
卸载挂钩
该功能在模块卸载后立即执行,卸载挂钩的参数是数据库游标和注册表。
您可以如下定义uninstall_hook
函数。
在清单文件中。
在您的__init__.py
文件中导入uninstall_hook
函数,并在hooks.py
文件中定义该函数,如下所示。
在hooks.py
文件内定义卸载钩子函数,如下所示:
您可以使用uninstall_hook
函数来完成模块的卸载过程,或者清除一些记录(以防通过API无法实现)。
加载后
根据odoo的推荐,post_load
用于
“调用模块的加载后挂钩。这可以在初始化任何模型或#data之前完成。可以,因为后加载挂钩是针对#server级(而不是特定于注册表的)功能。”
通常,这些功能用于猴子补丁。
猴子补丁:猴子补丁是指对类方法的动态或运行时修改,我们可以在运行时更改函数或代码的行为以获取所需的输出。
猴子补丁例如:
使用post_load
进行猴子修补的原因是,否则,当路径中可用猴子修补时,将每次应用猴子修补。通过使用post_load
,只有在安装了相应的模块后,它才会应用一次。
您可以按以下方式定义post_load
,
在模块的清单文件中添加post_load
函数名称,
将post_load
函数导入__init__.py
文件,并在hooks.py
文件中定义函数,如下所示。
您可以按上述方式使用post_load
,即使安装了模块,也将应用post_load
。
根据odoo文档,我们可以在安装或卸载模块时需要设置或清理的情况下使用挂钩,并且它们还建议仅在需要执行某些操作的同时使用此挂钩,而此模块和组件需要进行安装或卸载。通过API是非常困难或不可能的。