在 Odoo 中创建动态视图会破坏 MVC

Creating a dynamic view in Odoo breaks MVC

一段时间以来,我一直试图找出如何进行条件视图继承,即仅在满足条件时才修改视图。

继承的视图如下:

   <record id="invoice_tree_inherit" model="ir.ui.view">
        <field name="name">account.invoice.tree.inherit</field>
        <field name="model">account.invoice</field>
        <field name="inherit_id" ref="account.invoice_tree" />
        <field name="arch" type="xml">
                <data>
                    <xpath expr="//tree" position="replace">
                        <tree create="true"
                            colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'"
                            string="Invoice" visible="false">
                            <field name="number" />
                            <field name="date_invoice" />
                            <field name="partner_id" groups="base.group_user" />
                            <field name="commercial_partner_id" invisible="0" />
                            <field name="reference" invisible="1" />
                            <field name="name" invisible="1" />
                            <field name="journal_id" invisible="1" />
                            <field name="period_id" invisible="1"
                                groups="account.group_account_user" />
                            <field name="currency_id" groups="base.group_multi_currency" />
                            <field name="amount_total" sum="Total Amount" />
                            <field name="amount_tax" sum="IVA" />
                            <field name="state" />
                            <field name="comment" />
                            <field name="type" invisible="context.get('type',True)" />
                        </tree>
                    </xpath>
                </data>
        </field>
    </record>

但是我找不到一个令人满意的方法来让它继承视图,只有在满足条件的情况下。所以我选择了所描述的路线(在其他网站中)here.

我在 models.py 中编写的代码如下:

class Modulotest(models.Model):
    _inherit = 'account.invoice'

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context={}, toolbar=False):
        result = super(Modulotest, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar)
        if view_type=='tree' and result['name']=='account.invoice.tree':
            currUtente=self.pool.get('res.users').browse(cr,uid,uid,context)
            if currUtente.alt_view==True:
                result['arch']=self.getAltView()
        return result

    def getAltView(self):
        return '''
                <tree create="true" colors="blue:state == 'draft';black:state in ('proforma','proforma2','open');gray:state == 'cancel'" string="Fattura" visible="false">
                    <field name="number" modifiers="{&quot;readonly&quot;: true}"/>
                    <field name="date_invoice" modifiers="{&quot;readonly&quot;: [[&quot;state&quot;, &quot;not in&quot;, [&quot;draft&quot;]]]}"/>
                    <field name="partner_id" on_change="1" modifiers="{&quot;readonly&quot;: [[&quot;state&quot;, &quot;not in&quot;, [&quot;draft&quot;]]], &quot;required&quot;: true}" string="Cliente"/>
                    <field name="commercial_partner_id" invisible="1" modifiers="{&quot;readonly&quot;: true, &quot;tree_invisible&quot;: true}"/>
                    <field name="reference" invisible="1" modifiers="{&quot;tree_invisible&quot;: true}"/>
                    <field name="name" invisible="1" modifiers="{&quot;readonly&quot;: [[&quot;state&quot;, &quot;not in&quot;, [&quot;draft&quot;]]], &quot;tree_invisible&quot;: true}"/>
                    <field name="journal_id" invisible="1" modifiers="{&quot;readonly&quot;: [[&quot;state&quot;, &quot;not in&quot;, [&quot;draft&quot;]]], &quot;required&quot;: true, &quot;tree_invisible&quot;: true}"/>
                    <field name="period_id" invisible="1" modifiers="{&quot;invisible&quot;: true, &quot;readonly&quot;: [[&quot;state&quot;, &quot;not in&quot;, [&quot;draft&quot;]]], &quot;tree_invisible&quot;: true}"/>
                    <field name="currency_id" invisible="1" modifiers="{&quot;invisible&quot;: true, &quot;readonly&quot;: [[&quot;state&quot;, &quot;not in&quot;, [&quot;draft&quot;]]], &quot;required&quot;: true, &quot;tree_invisible&quot;: true}"/>
                    <field name="amount_total" sum="Importo Totale" modifiers="{&quot;readonly&quot;: true}"/>
                    <field name="amount_tax" sum="IVA" modifiers="{&quot;readonly&quot;: true}"/>
                    <field name="state" modifiers="{&quot;readonly&quot;: true}"/>
                    <field name="comment" modifiers="{}"/>
                    <field name="type" invisible="context.get('type',True)" modifiers="{&quot;readonly&quot;: true, &quot;tree_invisible&quot;: true}"/>
                </tree>
                 ''';

class UtenteEsteso(models.Model):
    _inherit =  'res.users'
    alt_view=fields.Boolean("Vista alternativa", default=False)

这个解决方案工作得很好,但是视图的元素是在模型中给出的,这不是我喜欢的。它打破了MVC架构模式。

我想要的是以某种方式从 views 文件夹中的 xml 文件中检索此字符串,但到目前为止,我还没有找到导入 xml 文件(或多个文件)的好方法一般而言)来自 odoo API.

如果有人知道如何做到这一点,或者知道我可以实现相同效果的替代方法,而无需在模型中包含视图元素,我将不胜感激!

在您的模型文件中,此代码有效

class Modulotest(models.Model):
    _inherit = 'account.invoice'

    @api.model
    def fields_view_get(self, view_id=None, view_type='form', toolbar=False):
        def get_view_id(xid, name):
            try:
                return self.env.ref('account.' + xid)
            except ValueError:
                view = self.env['ir.ui.view'].search([('name', '=', name)], limit=1)
                if not view:
                    return False
                return view.id
        result = super(Modulotest, self).fields_view_get(view_id, view_type, toolbar=toolbar)
        if view_type == 'tree' and result['name'] == 'account.invoice.tree':
            currUtente = self.env.uid
            if currUtente.alt_view:
                result['arch'] = get_view_id('invoice_tree_inherit', 'account.invoice.tree.inherit').id
        return result


class UtenteEsteso(models.Model):
    _inherit = 'res.users'
    alt_view = fields.Boolean("Vista alternativa", default=False)