Search 1.9 billion lines of Odoo code on GitHub

demo_fields_view_get_tutorial

Author: My Company
License: no license
Branch: master
Repository: twtrubiks/odoo-demo-addons-tutorial
Dependencies: account
Languages: Markdown (66, 60.0%), and Python (44, 40.0%)

<h1>odoo fields<em>view</em>get 介紹教學</h1> <p>建議觀看影片, 會更清楚:smile:</p> <ul> <li><a href="https://youtu.be/TpEw3TQiZ_M">Youtube Tutorial - odoo fields<em>view</em>get 介紹教學</a></li> </ul> <p>建議在閱讀這篇文章之前, 請先確保了解看過以下的文章 (因為都有連貫的關係)</p> <p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/master/demo_odoo_tutorial">odoo 手把手建立第一個 addons</a></p> <p>主要介紹 odoo 中 fields<em>view</em>get 這個 function 的功能以及用法.</p> <h2>說明</h2> <p>先說結論, 透過 <code>fields_view_get</code> 這個方法, 我們可以動態的做很多常規方法無法做到的事情,</p> <p>今天就來舉個例子, 我希望除了 Billing Manager 這個 groups 之外, 其他的人對 <code>account.invoice</code> 中的</p> <p><code>invoice_line_ids</code> field 都必須是 readonly (如圖下方).</p> <p><img src="https://i.imgur.com/VuIMx64.png" alt="alt tag"></p> <p>讓我們使用 <code>fields_view_get</code> 他來解決這個問題吧:smile: (常規的方法不好解決:sob:)</p> <p>請參考 <a href="models/account_invoice.py">models/account_invoice.py</a></p> <p>```python class AccountInvoice(models.Model): _inherit = &#39;account.invoice&#39;</p> <pre><code>@api.model def fields_view_get(self, view_id=None, view_type=&#39;form&#39;, toolbar=False, submenu=False): res = super(AccountInvoice, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) print(&#39;view_type:&#39;, view_type) if not self.env.user.has_group(&#39;account.group_account_manager&#39;): if view_type == &#39;form&#39;: doc = etree.XML(res[&#39;arch&#39;]) for node in doc.xpath(&#39;//field[@name=&quot;invoice_line_ids&quot;]&#39;): print(&#39;node.attrib dict:&#39;, node.attrib) node_values = node.get(&#39;modifiers&#39;) modifiers = json.loads(node_values) modifiers[&#39;readonly&#39;] = True node.set(&#39;modifiers&#39;, json.dumps(modifiers)) res[&#39;arch&#39;] = etree.tostring(doc) ...... return res </code></pre> <p>```</p> <p>先把這個 addons 裝起來, 當你在 invoice form 的介面底下看 terminal 的輸出訊息,</p> <p><img src="https://i.imgur.com/nMW9NQF.png" alt="alt tag"></p> <p>(你也可以把 <code>res[&#39;arch&#39;]</code> print 出來, 你就會發現 xml 的資料都包含在裡面)</p> <p>很明顯的, 當 type 要是 form 的時候才會有 xml 的資料, 主要是去修改 modifiers 裡面</p> <p>的資料, 要讓他變成是 <code>readonly=True</code>.</p> <p>(程式碼如上, 邏輯就是先抓到 <code>modifiers</code> 這個 node, 接著透過 json 的方式下去修改,</p> <p>最後記得要放回 arch, 也就是 <code>res[&#39;arch&#39;] = etree.tostring(doc)</code>)</p> <p>所以透過這段 code, 邏輯就是, 只有擁用 Billing Manager(<code>account.group_account_manager</code>)</p> <p>的 groups 才<strong>不是</strong> readonly, 否則都是 readonly. (建議看影片的 demo:smirk:)</p> <p>剛剛的 type 是 form, 接著來看看 tree 的狀況,</p> <p>```python class AccountInvoice(models.Model): _inherit = &#39;account.invoice&#39;</p> <pre><code>@api.model def fields_view_get(self, view_id=None, view_type=&#39;form&#39;, toolbar=False, submenu=False): res = super(AccountInvoice, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) print(&#39;view_type:&#39;, view_type) ....... if self.env.user.has_group(&#39;account.group_account_manager&#39;): if view_type == &#39;tree&#39;: doc = etree.XML(res[&#39;arch&#39;]) for node in doc.xpath(&#39;//field[@name=&quot;partner_id&quot;]&#39;): node.addnext( etree.Element(&#39;field&#39;, {&#39;string&#39;: &#39;test partner_id fields&#39;, &#39;name&#39;: &#39;partner_id&#39;})) res[&#39;arch&#39;] = etree.tostring(doc) return res </code></pre> <p>```</p> <p>當我們發現 type 是 tree 的時候, 且權限是 Billing Manager(<code>account.group_account_manager</code>),</p> <p>我們在 <code>partner_id</code> 的欄位後面再動態加一個 <code>partner_id</code> (名稱改為 test partner_id fields)</p> <p><img src="https://i.imgur.com/OMElix0.png" alt="alt tag"></p> <p>快速總結, 透過這個 <code>fields_view_get</code> 你可以做到很多非常規的變化, 也可以對 xml 做進一步的修改,</p> <p>達到動態的邏輯變化.</p>