使用弹出 window 获取用户输入并在 OpenERP 中的按钮功能中使用这些输入

Using popup window to get user inputs and use those inputs in button's function in OpenERP

我想请社区评估我在 OpenERP 中的解决方案。我正在使用 Odoo v8。

我创建了一个带有两个字段 original_code 和 replacement_code 的弹出窗口 window,以及标题为 "Replace" 的按钮。弹出窗口从 parent 页面 "More" 按钮下拉选项启动。

用例是用户将在字段 original_code 中输入产品代码(该字段看起来像编辑文本框),而替换代码字段会自动填充并且是只读的。按下按钮 "Replace" 将触发按钮操作,替换数据库中相关 table 中的代码。

我创建了新模型,新 class,因此在数据库 nk_product_template 中创建了新模型 table,它继承自 product_template。我创建新 table 的原因是让我的按钮操作在此 table 而不是 product_template table 中插入记录。我在 table、original_code 和替换代码中添加了两个新的字符字段。此模型在 XML 弹出窗口代码中引用 window。

我的按钮操作函数定义在class nk_product_template 中,它的名称是action_replace(),它具有替换产品代码的逻辑。每当我单击按钮 "Replace" 时,它总是首先在 table nk_product_template 中插入记录(没有为插入编写代码,据我所知它是自动的)和 returns id我用来从按钮 action_replace() 内的 table 检索 original_code 和 replacement_code 值的记录,并在代码替换逻辑中使用这些值。

我想知道这是解决用例的正确方法吗?如果不是正确的方法,您将如何解决。我的主要问题是我是否需要为每个弹出窗口 window 设置新的 class(因此需要新的模型和新的 table)来设置和获取字段值?非常感谢您的评论。

这是定义弹出 window 的 XML 代码:

<record id="replace_all_in_BOM_form" model="ir.ui.view">
    <field name="name">replace.all.in.BOM.form</field>
    <field name="model">nk.product.template</field>
    <field name="priority" eval="20"/>
    <field name="type">form</field>
    <field name="arch" type="xml">
        <group>
            <field name="original_code" string="Original Code" style="width: 
            10%%" readonly="0" />
            <field name="replacement_code" string="Replacement Code" 
            style="width: 10%%" readonly="1" invisible="0" />
            <field name="default_code" string="Replacement" readonly="1"    
            invisible="1"  />   
            <field name="uom_id" invisible="1"  /> 
            <field name="uom_po_id" invisible="1"   />
            <field name="type" invisible="1"   />   
            <field name="categ_id" invisible="1"   /> 
            <field name="name" invisible="1" />
        </group>
        <button type="object" string="Replace" name="action_replace" />
    </field> 
</record>

我的py代码如下:

class nk_product_template(osv.osv):
    _inherit = 'product.template'
    _name = 'nk.product.template'

    _columns = {
        'replacement_code' : fields.char('Replacement Code', select=True),
        'original_code' : fields.char('Original Code', select=True),
    }
    def default_get(self, cr, uid, fields, context=None):
        # <code to automatically populate replacement_code field>
        # ...   

    def action_replace(self, cr, uid, ids, context=None):
        # <code that replaces product code>
        # ...

不需要继承product.template。只需创建一个引用您要更改的模板的 one2many 字段。

此外,nk.product.template 似乎应该是 TransientModel 而不是普通模型。瞬态模型的对象只是暂时存在的,不会无限期地存储在数据库中。它们适用于辅助函数和向导 - 就像您拥有的那样。

要使用瞬态模型,而不是从 osv.osv 继承您的 class,只需从 osv.osv_memory 继承它。或者甚至更好,而不是使用已弃用的 osv,对正常模型使用 models.Model,对瞬态模型使用 models.TransientModel(代替 osv.osvosv.osv_memory) .

我要更改的最后一件事是您使用旧的 ORM API。它过于冗长且难以阅读,并且会在某个时候从新的 Odoo 版本中删除。使用新的 Odoo ORM 会好得多。


新模型可能看起来像这样(显然我不知道具体细节,所以这只是一个例子):

from openerp import models, fields, api


class ProductCodeWizard(models.TransientModel):
    _name = 'nk.code_wizard'

    template = fields.Many2one(
        'product.template',
        required=True,
        default=lambda self: self.env.context['active_id'],
    )
    replacement_code = fields.Char(string="Replacement Code")
    original_code = fields.Char(
        string="Original Code",
        related='template.default_code',
        readonly=True,
    )

    @api.one
    def action_replace(self):
        self.template.default_code = self.replacement_code

您可以阅读有关新 ORM 的更多信息 API here and here. You can also watch presentations here and here