Author: |
My Company |
License: |
no license |
Branch: |
master |
Repository: |
twtrubiks/odoo-demo-addons-tutorial |
Dependencies: |
base |
Languages: |
Markdown (87, 48.3%),
Python (50, 27.8%),
and
XML (43, 23.9%) |
<h1>透過 AbstractModel 擴充 Model</h1>
<p>建議觀看影片, 會更清楚:smile:</p>
<p><a href="https://youtu.be/uW1PsDPcJF4">Youtube Tutorial - odoo 手把手教學 - 透過 AbstractModel 擴充 Model</a></p>
<p>之前有介紹過 AbstractModel 的文章</p>
<ul>
<li><p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_abstractmodel_tutorial">介紹 AbstractModel</a> 搭配 report 使用</p></li>
<li><p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_prototype_inheritance">odoo 繼承 - prototype inheritance</a> 有提到 MailThread 這個 AbstractModel</p></li>
</ul>
<p>今天要來進一步介紹, 如何透過 AbstractModel 擴充 Model:smile:</p>
<h2>說明</h2>
<p>首先, 再提一次</p>
<p><code>AbstractModel</code> AbstractModel = BaseModel,</p>
<p>注意:exclamation::exclamation: AbstractModel <strong>不會</strong> 在資料庫中產生對應的 table.</p>
<p>先來看這個範例 <a href="models/models.py">models/models.py</a></p>
<p>```python
from odoo import models, fields, api</p>
<p>class DemoMixin(models.AbstractModel):
_name = 'demo.mixin'
_description = 'Demo Mixin'</p>
<pre><code>test_1 = fields.Float(
string='test_1',
default='2.2'
)
test_2 = fields.Float(
string="test_2",
compute="_compute_field",
)
def _compute_field(self):
for record in self:
record.test_2 = 3.0
</code></pre>
<p>class DemoModelTutorial(models.Model):
_name = 'demo.model.tutorial'
_inherit = 'demo.mixin'
_description = 'Demo Model Tutorial'</p>
<pre><code>name = fields.Char(required=True, string="名稱")
</code></pre>
<p>```</p>
<p>這邊 <code>demo.model.tutorial</code> 繼承了 <code>demo.mixin</code>, 所以在 db table 中,</p>
<p>會看到 <code>demo.mixin</code> 中的 fields.</p>
<p><img src="https://i.imgur.com/0fYEUiS.png" alt="alt tag"></p>
<p>這邊稍微注意注意一下,</p>
<p>在 db 中只會有 <code>demo.model.tutorial</code> 的 table, 不會有 <code>demo.mixin</code> 的 table,</p>
<p>但是會有 <code>demo.mixin</code> 中的 fields, 也看不到 <code>test_2</code> fields, 原因是他是 <em>compute</em>field,</p>
<p>如果你想要看到包含 <code>test_2</code> fields, 可以到 odoo 的 model 後台觀看</p>
<p><img src="https://i.imgur.com/oiASNIP.png" alt="alt tag"></p>
<p><code>demo.mixin</code> 的 model 在 odoo 的後台也可以觀看 (但 db 中不會出現)</p>
<p><img src="https://i.imgur.com/HkftQT3.png" alt="alt tag"></p>
<p><img src="https://i.imgur.com/3ttRkzP.png" alt="alt tag"></p>
<p>在 tree, form ...... 都可以使用 <code>demo.mixin</code> 的 fields</p>
<p><img src="https://i.imgur.com/hFCf2mR.png" alt="alt tag"></p>
<p>因為這個範例剛好只有一個 model 被繼承, 如果有兩個以上的 model 就更適合這樣寫了, 如下</p>
<p>```python
......</p>
<p>class DemoModelTutorial(models.Model):
_name = 'demo.model.tutorial'
_inherit = 'demo.mixin'
_description = 'Demo Model Tutorial'</p>
<pre><code>......
</code></pre>
<p>class DemoModelTutorial_v2(models.Model):
_name = 'demo.model.tutorial.v2'
_inherit = 'demo.mixin'
_description = 'Demo Model Tutorial v2'</p>
<pre><code>......
</code></pre>
<p>class DemoModelTutorial_v3(models.Model):
_name = 'demo.model.tutorial.v3'
_inherit = 'demo.mixin'
_description = 'Demo Model Tutorial v3'</p>
<pre><code>......
</code></pre>
<p>```</p>
<p>這樣每個 model, 都會擁有 <code>demo.mixin</code> 的 fields, 不需要把重複的 code</p>
<p>在每個 model 中都寫一遍.</p>
<p>剛剛介紹的 model 是我們新建立的, 假如今天有一個 model 已經存在了,</p>
<p>想要用同樣的方式擴充 model, 可參考 <a href="models/models_v2.py">models/models_v2.py</a></p>
<p>```python
from odoo import models, fields, api</p>
<p>class DemoMixin2(models.AbstractModel):
_name = 'demo.mixin2'
_description = 'Demo Mixin2'</p>
<pre><code>test_v2 = fields.Float(
string='test_v2',
default='2.2'
)
</code></pre>
<p>class DemoModelTutorial(models.Model):
_name = 'demo.model.tutorial'
_inherit = ['demo.model.tutorial', 'demo.mixin2']</p>
<pre><code>pass
</code></pre>
<p>```</p>
<p>這篇文章其實就是將 <a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_sale_scan_barcode">odoo 實作 scan barcode</a> 的概念再說一次.</p>
<p>也可以去了解一下 <a href="https://github.com/twtrubiks/python-notes/tree/master/what_is_the_mixin">什麼是 Mixin in python</a>,</p>
<p>相信這樣大家會更了解他們的概念:smile:</p>