Chapter 9: Ready For Some Action?

So far we have mostly built our module by declaring fields and views. We just introduced business logic in the previous chapter thanks to computed fields and onchanges. In any real business scenario, we would want to link some business logic to action buttons. In our real estate example, we would like to be able to:

  • 取消或将属性标记为已售

  • 接受或拒绝一个报价

有人可能会认为我们已经可以通过手动更改状态来完成这些事情,但这并不是很方便。此外,我们还想添加一些额外的处理:当接受报价时,我们想要设置房产的销售价格和买家。

对象类型

Reference: the documentation related to this topic can be found in 操作 and 错误管理.

注解

目标:在本节结束时:

  • 您应该能够取消或将属性标记为已售:

取消并设置为已售出

A cancelled property cannot be sold and a sold property cannot be cancelled. For the sake of clarity, the state field has been added on the view.

  • 您应该能够接受或拒绝一个报价:

接受或拒绝一个报价
  • 一旦接受了报价,应设置销售价格和买家:

接受一个报价

在我们的房地产模块中,我们想要将业务逻辑与一些按钮链接起来。最常见的方法是:

  • 在视图中添加一个按钮,例如在视图的 header 中:

<form>
    <header>
        <button name="action_do_something" type="object" string="Do Something"/>
    </header>
    <sheet>
        <field name="name"/>
    </sheet>
</form>
  • 并将此按钮链接到业务逻辑:

from odoo import fields, models

class TestAction(models.Model):
    _name = "test.action"

    name = fields.Char()

    def action_do_something(self):
        for record in self:
            record.name = "Something"
        return True

通过将 type="object" 分配给我们的按钮,Odoo框架将在给定的模型上执行一个名为 name="action_do_something" 的Python方法。

首先要注意的重要细节是,我们的方法名没有前缀下划线( _ )。这使得我们的方法成为一个 公共 方法,可以直接从Odoo界面调用(通过RPC调用)。到目前为止,我们创建的所有方法(compute,onchange)都是在内部调用的,所以我们使用了以下划线为前缀的 私有 方法。除非需要从用户界面调用,否则您应该始终将方法定义为私有方法。

同时请注意我们在 self 上进行循环。始终假设一个方法可以在多个记录上调用;这样更有利于可重用性。

最后,一个公共方法应该始终返回一些内容,以便可以通过XML-RPC进行调用。如果不确定,只需 return True

在Odoo源代码中有数百个示例。一个示例是这个 视图中的按钮 <https://github.com/odoo/odoo/blob/cd9af815ba591935cda367d33a1d090f248dd18d/addons/crm/views/crm_lead_views.xml#L9-L11> __和它的 对应的Python方法 <https://github.com/odoo/odoo/blob/cd9af815ba591935cda367d33a1d090f248dd18d/addons/crm/models/crm_lead.py#L746-L760> __

Exercise

取消并将属性标记为已售。

  • Add the buttons ‘Cancel’ and ‘Sold’ to the estate.property model. A cancelled property cannot be set as sold, and a sold property cannot be cancelled.

    请参考 目标 的第一张图片以获取预期结果。

    提示:为了引发错误,您可以使用 UserError 函数。在Odoo源代码中有很多示例;-)

  • estate.property.offer 模型中添加按钮 ‘Accept’ 和 ‘Refuse’。

    请参考 目标 的第二张图片以获取预期结果。

    提示:要将图标用作按钮,请查看 此示例.

  • 当一个报价被接受时,为相应的房产设置买家和销售价格。

    请参考 目标 的第三张图片以获取预期结果。

    注意:在现实生活中,对于一处房产,只能接受一个报价!

操作类型

In Chapter 5: Finally, Some UI To Play With, we created an action that was linked to a menu. You may be wondering if it is possible to link an action to a button. Good news, it is! One way to do it is:

<button type="action" name="%(test.test_model_action)d" string="My Action"/>

我们使用 type="action" 并且我们在 name 中引用 外部标识符

In the next chapter we’ll see how we can prevent encoding incorrect data in Odoo.