【问题标题】:How to make a field computed only if some condition is fulfilled in Odoo 8?如何仅在 Odoo 8 中满足某些条件时才计算字段?
【发布时间】:2016-02-09 13:20:24
【问题描述】:

Odoo 8 中是否有任何方法可以创建仅在满足某些条件时才计算的字段,否则用户将能够设置其值?

示例

我有一个名为 box 的模型,它有一个名为 value 的浮点字段。

想象一个盒子里面可以有几个盒子,每个盒子都有自己的价值。

所以我们有一个名为child_ids 的one2many 字段指向box,还有一个名为parent_id 的many2one 也指向box。

现在我想要以下行为:用户可以设置一个没有任何盒子的盒子的 value 字段(这意味着,childs_idsFalse),但是,如果盒子里面至少有一个盒子(这意味着,childs_ids 不是 False),必须计算 value 字段,它将是其子 value 的总和。

有人知道如何实现这种行为吗?

我输入了我的代码,但它不起作用(value 的值总是被重置为 0):

class box(models.Model):
    _name='box'

    @api.one
    @api.depends('child_ids', 'child_ids.value')
    def _compute_value(self):
        if self.child_ids:
            self.value = sum(
                [child.value for child in self.child_ids])

    def _set_value(self):
        pass

    parent_id = fields.Many2one(comodel_name='box',
                                string='Parent Box')

    child_ids = fields.One2many(comodel_name='box',
                                inverse_name='parent_id',
                                string='Boxes inside')

    value = fields.Float(
        string='Value',
        compute='_compute_value',
        inverse='_set_value',
        store=False,
        required=True,
        readonly=True,
        states={'draft':[('readonly',False)]},
    )

【问题讨论】:

    标签: python-2.7 openerp odoo-8


    【解决方案1】:

    在模型中

    computed_field = fields.Char(compute='comp', inverse='inv', store=True)
    boolean_field = fields.Boolean()
    
    @api.one
    def comp(self):
        ...
    
    @api.one
    def inv(self):
        ...
    

    在视图中

    <field name="boolean_field" />
    <field name="computed_field" attrs="{'readonly': [('boolean_field','=',True)]}" />
    

    编辑:

    现在您的示例更清楚了,我想说您应该更改以下内容:

    valuestore 参数设置为 True 而不是 False 并删除 inverse 在你的情况下,你不需要。

    那么你需要另外 2 个字段

    value_manual = fields.Float()
    manual = fields.Boolean(compute='_is_manual', default=True)
    
    @api.one
    @api.depends('child_ids')
    def _is_manual(self):
        self.manual = len(self.child_ids) == 0
    

    @api.one
    @api.depends('child_ids', 'child_ids.value')
    def _compute_value(self):
        if self.child_ids:
            self.value = sum(
                [child.value for child in self.child_ids])
        else:
            self.value = self.value_manual
    

    在视图中:

    <field name="manual" invisible="1" />
    <field name="value" attrs="{'invisible': [('manual','=',True)]}" />
    <field name="value_manual" attrs="{'invisible': [('manual','=',False)]}" />
    

    可能有另一种解决方案可以避免这个双场,也许使用逆向,但我不确定。

    【讨论】:

    • 谢谢@Alessandro,现在我知道我必须使用inverse参数,但是我在任何地方都找到的示例是get_document-set_document一个,这不太好理解.我找到的最好的一个是在partner_street_number 模块中,但即便如此,我还是无法理解我必须在inv 方法中写什么(目的是如果boolean_fieldFalse,则什么也不做,保留用户设置的值)。
    • 这取决于,即使除了存储值之外您不需要任何特定操作。在这种情况下,您可以跳过 inverse 参数
    • 嗨@Alessandro,我已经用一个更好的例子更新了我的问题并添加了代码以使其更易于理解。我还必须使用inverse 参数吗?请问inverse方法可以帮我吗?
    • 您好,我尝试根据您的示例改进我的解决方案
    • 非常感谢@Alessandro 的努力。这是一个很好的解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    相关资源
    最近更新 更多