Author: |
My Company |
License: |
no license |
Branch: |
master |
Repository: |
twtrubiks/odoo-demo-addons-tutorial |
Dependencies: |
base |
Languages: |
Markdown (56, 65.9%),
and
Python (29, 34.1%) |
<h1>odoo 觀念 - 實作 init hook</h1>
<p>建議觀看影片, 會更清楚:smile:</p>
<p><a href="https://youtu.be/2ZmfH3wBHm8">Youtube Tutorial - odoo 手把手教學 - 實作 init hook</a></p>
<p>建議在閱讀這篇文章之前, 請先確保了解看過以下的文章 (因為都有連貫的關係)</p>
<p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_odoo_tutorial">odoo 手把手建立第一個 addons</a></p>
<p>本篇文章主要介紹 odoo 中的 init hook 這部份</p>
<h2>說明</h2>
<p>還記得之前我們介紹過 <a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_odoo_tutorial#%E4%BB%8B%E7%B4%B9-security-menu-tree-form">介紹 security, menu, tree, form</a></p>
<p>裡面有提到很多時候會透過 <code>data/xxx.xml</code> 的方式自動產生一些預設資料,</p>
<p>但是, 有時候我們的邏輯比較複雜, 無法簡單的使用 xml 表示, 這時候, 就可以透過 hook 的方式.</p>
<p>先來看 <code>__manifest__.py</code></p>
<p>```python
{
......</p>
<pre><code>'pre_init_hook': 'pre_init_hook',
'post_init_hook': 'post_init_hook',
'uninstall_hook': 'uninstall_hook',
'post_load': 'post_load_hook',
'application': True,
</code></pre>
<p>}</p>
<p>```</p>
<p>在 odoo 中, hook 總共有 4 種,</p>
<p><code>pre_init_hook</code> 在安裝 addons 之前, 會先執行他, 執行完畢後, 才開始安裝 addons. (更新不會生效)</p>
<p><code>post_init_hook</code> 在安裝 addons 完之後, 才會執行他. (更新不會生效)</p>
<p><code>uninstall_hook</code> 在移除 addons 完之後, 才會執行他.</p>
<p><code>post_load</code> 這個比較特殊, 他只會生效在當你使用 odoo-bin CLI 安裝或更新時, 優先於 <code>pre_init_hook</code>.</p>
<p><code>post_load</code> 比較進階, 常常搭配 <a href="https://github.com/twtrubiks/fluent-python-notes/tree/master/what_is_the_Monkey_Patch">介紹 Monkey Patch</a>, 請參考 odoo source code.</p>
<p>請參考 <code>__init__.py</code></p>
<p>```python
from odoo import api, SUPERUSER_ID</p>
<p>import logging</p>
<p><em>logger = logging.getLogger(</em><em>name</em>_)</p>
<p>def pre<em>init</em>hook(cr):
env = api.Environment(cr, SUPERUSER_ID, {})
# data = env[......].search([......])</p>
<pre><code>_logger.warning('=== pre_init_hook ===')
</code></pre>
<p>def post<em>init</em>hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
# data = env[......].search([......])</p>
<pre><code>_logger.warning('=== post_init_hook ===')
</code></pre>
<p>def uninstall<em>hook(cr, registry):
env = api.Environment(cr, SUPERUSER</em>ID, {})
# data = env[......].search([......])</p>
<pre><code>_logger.warning('=== uninstall_hook ===')
</code></pre>
<p>def post<em>load</em>hook():
<em>logger.warning('=== post</em>load_hook ===')
```</p>
<p>當我們透過 odoo-bin CLI 安裝 addons 時,</p>
<p>執行順序為 <code>post_load_hook</code> -> <code>pre_init_hook</code> -> <code>post_init_hook</code></p>
<p>(如果從 odoo 介面安裝 addons 則不會有 <code>post_load_hook</code> )</p>
<p><img src="https://i.imgur.com/zFeoeNl.png" alt="alt tag"></p>
<p>從 odoo 介面移除 addons</p>
<p><img src="https://i.imgur.com/viGukst.png" alt="alt tag"></p>
<p>透過這個方法, 當我們在安裝或是移除 addons 時, 可以針對資料面再進行一次檢查或清理.</p>
<p>像是有時候繼承既有的 rule, 當你移除 addons 時, 該 rule 並不會被還原,</p>
<p>這時候, 就可以用 hook 的方式來處理:satisfied:</p>