Author: |
|
License: |
AGPL-3 |
Branch: |
14.0 |
Repository: |
twtrubiks/odoo-demo-addons-tutorial |
Dependencies: |
mail |
Languages: |
Markdown (90, 48.6%),
Python (29, 15.7%),
and
XML (66, 35.7%) |
Other branches: |
master |
<h1>odoo 繼承 - prototype inheritance</h1>
<p>建議觀看影片, 會更清楚:smile:</p>
<p><a href="https://youtu.be/sJrik0jjuas">Youtube Tutorial - odoo 繼承 - prototype inheritance</a></p>
<p>建議在閱讀這篇文章之前, 請先確保了解看過以下的文章 (因為都有連貫的關係)</p>
<p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_class_inheritance">odoo 繼承 - class inheritance</a></p>
<p>本篇文章主要介紹 prototype inheritance 這部份</p>
<h2>說明</h2>
<p><code>_inherit</code> prototype inheritance</p>
<p>注意:exclamation: 還有一個是 <code>_inherits</code>, 不要搞錯了哦.</p>
<p><img src="https://i.imgur.com/kjtCar6.png" alt="alt tag"></p>
<p>注意:exclamation: Stored in different tables.</p>
<p>注意:exclamation: 此類別會擁有父類別的所有特性, 在此類別中的任何修改, 都不會去影響到父類別.</p>
<p>class inheritance 和 prototype inheritance 其實很好分辨,</p>
<p>prototype inheritance 會自己額外定義新的 <code>_name</code>,</p>
<p>(注意:exclamation: 如果 <code>_name</code> 和被繼承/父類別的名稱一樣, 就等同是 <strong>class inheritance</strong> 哦)</p>
<p>使用的時機通常是繼承 <code>mail.thread</code> 這類的 <code>models.AbstractModel</code>,</p>
<p>可參考 <a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_abstractmodel_tutorial">odoo 手把手教學 - AbstractModel</a>.</p>
<p><a href="models/model.py">models/model.py</a></p>
<p>```python
......
class PrototypeInheritance(models.Model):
_name = 'demo.prototype'
_description = 'PrototypeInheritance'
_inherit = ['mail.thread']</p>
<pre><code># 'demo.prototype' 擁有 'mail.thread'(父類別) 的所有特性,
# 在這裡面的修改, 都不會去影響到 'mail.thread'(父類別).
test_field = fields.Char('test_field')
</code></pre>
<p>```</p>
<p>db 中的狀況</p>
<p><img src="https://i.imgur.com/DdOAF2b.png" alt="alt tag"></p>
<p><a href="views/views.xml">views/views.xml</a></p>
<p><code>xml
......
<record id="view_tree_demo_prototype_tutorial" model="ir.ui.view">
<field name="name">Demo Prototype List</field>
<field name="model">demo.prototype</field>
<field name="arch" type="xml">
<tree>
<field name="test_field"/>
</tree>
</field>
</record>
......
</code></p>
<p><a href="views/views.xml">views/views.xml</a></p>
<p>form 的部份</p>
<p><code>xml
......
<record id="view_form_demo_prototype_tutorial" model="ir.ui.view">
<field name="name">Demo Prototype Form</field>
<field name="model">demo.prototype</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="test_field"/>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
......
</code></p>
<p>在這邊可以使用 <code>message_follower_ids</code> <code>message_ids</code> 的原因是因為繼承了 <code>mail.thread</code></p>
<p><img src="https://i.imgur.com/1x3qwGZ.png" alt="alt tag"></p>
<p><img src="https://i.imgur.com/NGhD6H9.png" alt="alt tag"></p>
<p>因為它是 prototype inheritance, 所以在 db 中的 <code>demo_prototype</code> 是不會有 message 的資訊的.</p>
<p><code>mail.thread</code> odoo 原始碼的路徑 <code>addons/mail/models/mail_thread.py</code></p>
<p>```python
class MailThread(models.AbstractModel):
......
<em>name = 'mail.thread'
_description = 'Email Thread'
_mail</em>flat<em>thread = True # flatten the discussino history
_mail</em>post_access = 'write' # access required on the document to post on it
_Attachment = namedtuple('Attachment', ('fname', 'content', 'info'))</p>
<p>......
message<em>follower</em>ids = fields.One2many(
'mail.followers', 'res_id', string='Followers')</p>
<p>......</p>
<p>message<em>ids = fields.One2many(
'mail.message', 'res</em>id', string='Messages',
domain=lambda self: [('message<em>type', '!=', 'user</em>notification')], auto_join=True)
......
```</p>
<p>從 <code>mail.thread</code> 可以看出它分別儲存在 <code>mail.followers</code> 和 <code>mail.message</code> table 中.</p>