跳至内容

老赵解读Odoo 18开发教程13:与其他模块协作

2026年8月15日
老赵解读Odoo 18开发教程13:与其他模块协作

原文:Odoo 18 官方开发教程“Server framework 101”第 13 章。本文尽量保留原文结构、代码、练习与图片,仅进行中文翻译,并在文末增加“老赵解读”。

第 13 章:与其他模块交互


上一章中,我们使用继承来
修改模块的行为。在我们的房地产场景中,我们想更进一步
并能够为我们的客户生成发票。 Odoo 提供了一个 Invoicing 模块,所以它
直接从我们的房地产模块创建发票会很方便,即一旦房产
设置为“已售出”,发票将在发票应用程序中创建。

具体示例:账户转移

说明

目标: 在本节末尾:

  • 应创建一个新模块 estate_account
  • 当房产售出时,应为买方开具发票

Invoice creation

任何时候我们与另一个模块交互时,我们都需要牢记模块化。如果我们打算
将我们的应用程序出售给房地产机构,有些人可能需要发票功能,但是
其他人可能不想要它。

链接模块

此类用例的常见方法是创建一个“链接”模块。在我们的例子中,模块
将取决于 estateaccount 并将包含发票创建逻辑
庄园房产。这样就可以安装房地产和会计模块
独立。当两者都安装时,链接模块提供新功能。

练习

创建链接模块。

创建 estate_account 模块,该模块依赖于 estateaccount 模块。
目前,它只是一个空壳。

提示:您已经在
教程开始。过程很
类似。

estate_account 模块出现在列表中时,继续安装它!你会注意到
发票应用程序也已安装。这是预期的,因为您的模块依赖于它。
如果您卸载发票应用程序,您的模块也将被卸载。

发票创建

现在是生成发票的时候了。我们想要添加功能
estate.property模型,即我们希望在售出房产时添加一些额外的逻辑。
这听起来很熟悉吗?如果没有,最好返回
上一章 因为您可能错过了
某事;-)

第一步,我们需要扩展按下按钮时调用的操作
房产上的 “已售出”按钮。为此,我们需要
estate_account 中创建 模型继承
estate.property模型的模块。目前,覆盖的操作将简单地返回
super 调用。也许一个例子会让事情变得更清楚:

from odoo import models

class InheritedModel(models.Model):
    _inherit = "inherited.model"

    def inherited_action(self):
        return super().inherited_action()

可以找到一个实际的例子
这里

练习

添加发票创建的第一步。

  • estate_account 模块的正确文件夹中创建 estate_property.py 文件。
  • _inherit estate.property模型。
  • 重写 action_sold 方法(您可能以不同的方式命名)以返回 super
    打电话。

提示:为了确保其正常工作,请在重写的方法中添加 print 或调试器断点。

有效吗?如果没有,也许检查所有 Python 文件是否都正确导入。

如果覆盖有效,我们可以继续并创建发票。不幸的是,有
想要知道如何在 Odoo 中创建任何给定对象并不简单。大多数时候,是有必要的
查看其模型以找到所需的字段并提供适当的值。

一个好的学习方法是查看其他模块如何完成您想做的事情。例如,其中之一
销售的基本流程是根据销售订单创建发票。这看起来不错
起点,因为它正是我们想做的。花一些时间阅读并理解
_创建_发票
方法。当你因为这个简单的任务看起来非常复杂而哭泣时,我们可以移动
在教程中转发。

要创建发票,我们需要以下信息:

  • partner_id:客户
  • a move_type:它有几个 可能的值
  • a journal_id:会计日记帐

这足以创建一张空发票。

练习

添加发票创建的第二步。

action_sold 方法的重写中创建一个空的 account.move

  • partner_id 取自当前的 estate.property
  • move_type 应对应于“客户发票”

温馨提示:

  • 要创建对象,请使用 self.env[model_name].create(values),其中 values
    dict
  • create 方法不接受记录集作为字段值。

当房产设置为“已售出”时,您现在应该在以下位置创建新的客户发票:
发票/客户/发票。

显然,到目前为止我们还没有任何发票行。要创建发票行,我们需要以下内容
信息:

  • name:该行的描述
  • quantity
  • price_unit

此外,发票行需要链接到发票。最简单、最有效的方法
将行链接到发票就是包含发票创建时的所有行。为此,需要将
invoice_line_ids字段包含在 account.move 创建中,这是一个
One2many。 One2many 和 Many2many 使用特殊的“命令”
使用 Command 命名空间使人类可读。这个命名空间代表
在一组记录上执行的三元组命令。三胞胎原本是唯一的选择
执行这些命令,但现在使用命名空间已成为标准。格式是放置
它们在一个按顺序执行的列表中。这是一个包含 One2many 的简单示例
字段 line_ids 创建 test_model 时:

from odoo import Command

def inherited_action(self):
    self.env["test_model"].create(
        {
            "name": "Test",
            "line_ids": [
                Command.create({
                    "field_1": "value_1",
                    "field_2": "value_2",
                })
            ],
        }
    )
    return super().inherited_action()

练习

添加发票创建的第三步。

在创建 account.move 期间添加两个发票行。每售出一本房产
根据以下条件开具发票:

  • 售价的6%
  • 额外 100.00 行政费

提示:按照上面的示例在创建时添加 invoice_line_ids
对于每一行,我们都需要 namequantityprice_unit

本章可能是迄今为止最困难的一章,但也是最接近的一章
Odoo 开发的实际情况。在下一章中,我们将介绍Odoo中使用的模板机制。

老赵解读

与其他模块协作的本质,是在清晰依赖关系下复用已有业务能力。教程把房地产与发票连接起来,展示了一个典型原则:业务模块只提供自己的领域逻辑,通用能力应交给会计等专业模块处理。

跨模块开发要避免隐式耦合。凡是代码、字段或 XML 引用了另一个模块的资源,都应在 manifest 中声明依赖;可选集成则更适合拆成独立桥接模块,让两个主模块仍可单独安装。

老赵解读Odoo 18开发教程12:继承与扩展