上一章介绍了为包含基本字段的模型创建自定义视图。然而,在任何实际业务场景中,我们都需要不止一个模型。此外,模型之间的联系是必要的。可以很容易地想象一个模型包含客户,另一个包含用户列表。您可能需要就任何现有业务模型向客户或用户推荐。
在我们的房地产模块中,我们需要有关房产的以下信息:
参考:与本主题相关的文档可以在Many2one中找到。
备注
目标:在本节末尾:
在我们的房地产模块中,我们想定义房地产类型的概念。例如,属性类型是房屋或公寓。标准的业务需要是根据属性的类型对其进行分类,尤其是优化过滤。
属性具有一种类型,但是可以将相同类型分配给多个属性。这就是Many2one
的概念。
Many2one
是指向另一个对象的简单链接。例如,为了在我们的测试模型中定义到res.partner
的链接,我们可以写下:
partner_id = fields.Many2one("res.partner", string="Partner")
按照惯例,Many2one
字段具有_id
后缀。然后,可以使用以下工具轻松访问合作伙伴中的数据:
print(my_test_object.partner_id.name)
另请参见
外键
在实践中,Many2one
可以看作是表单视图中的下拉列表。
练习
添加不动产属性类型表。
- 创建
estation.property.type
模型并添加以下字段:
字段 类型 属性 name Char required - 添加本节目标中显示的菜单
- 将字段
property_type_id
添加到您的estation.property
模型及其表单,树和搜索视图此练习是前几章的良好回顾:您需要创建模型,设置模型,添加动作和菜单并创建视图。
提示:不要忘记在__init__.py
中导入任何新的python文件,在__manifest__.py
中添加新数据文件或添加访问权限;
再次重启服务器并刷新以查看结果!
在房地产模块中,我们仍然需要两条缺失的房产信息:买家和销售人员。买方可以是任何个人,但另一方面,销售人员必须是房地产代理的员工(即Odoo用户)。
在Odoo中,我们通常提到两种模型:
res.partner
:合作伙伴是物理或法人实体。它可以是一家公司,个人甚至联系地址。res.users
:系统的用户。用户可以是“内部”,即他们可以访问Odoo平台后台。或者它们可以是“门户”,即他们无法访问平台后台,只有前台(例如,在电子商务中访问他们以前的订单)。练习
添加买家和销售人员。
使用上面提到的两个通用模型,将买家和销售人员添加到estation.property
模型。如本节的目标所示,应将它们添加到表单视图的新选项卡中。
销售人员的默认值必须是当前用户。买方不得复制。
提示:要获取默认值,请检查下面的注释或在此处(L92行)查看示例。
备注
对象self.env
可以访问请求参数和其他有用的内容:
self.env.cr
或self._cr
:数据库游标对象;用于查询数据库self.env.uid
或self._uid
:当前用户的数据库idself.env.user
:当前用户的记录self.env.context
或self._context
:上下文词典self.env.ref(xml_id)
:返回与xml_id对应的记录self.env[model_name]
:返回给定模型的实例
现在,让我们看一下其他类型的链接。
参考:与此主题相关的文档可以在Many2many中找到。
备注
目标:在本节末尾:
在我们的房地产模块中,我们要定义属性标签的概念。属性标签是例如“cozy”或“renovated”的属性。
属性可以具有多个标签,并且可以将标签分配给多个属性。这就是Many2many
的概念。
Many2many
是一个双向多重关系:一侧的任何记录都可以与另一侧的任何数量记录有关。例如,为了在我们的测试模型上定义指向account.tax
模型的链接,我们可以写下:
tax_ids = fields.Many2many("account.tax", string="Taxes")
按照惯例,Many2many
的字段具有_ids
后缀。这意味着可以向我们的测试模型中添加几种tax。它的行为类似于记录列表,这意味着访问数据必须在循环中完成:
for tax in my_test_object.tax_ids:
print(tax.name)
记录列表称为recordset
,即有序的记录集合。它支持集合上的标准Python操作,如len()
和iter()
,以及额外的集合操作,如recs1 | recs2
。
练习
添加不动产属性标记表。
- 创建
estation.property.tag
模型并添加以下字段:
字段 类型 属性 name Char required - 添加本节目标中显示的菜单
- 将字段
tag_ids
添加到您的estation.property
模型及其表单和树视图提示:在视图中,请使用此处(L36行)所示的
widget="many2many_tags"
属性。widget
属性将在培训的后章中详细说明。目前,您可以尝试添加和删除它并查看结果;
参考:与本主题相关的文档可以在One2many中找到。
备注
目标:在本节末尾:
在我们的房地产模块中,我们想定义财产报价的概念。物业优惠是潜在买家向卖方提供的金额。报价可以低于预期价格。
报价适用于一处房产,但同一处房产可以有多处报价。many
的概念再次出现。然而,在本例中,我们希望显示给定属性的报价列表,因此我们将使用one2many
概念。
one2many
是many2one
的倒数。例如,基于字段partner_id,我们在测试模型上定义了到res.partner模型的链接。我们可以定义反向关系,即与我们的合作伙伴链接的测试模型列表:
test_ids = fields.One2many("test.model", "partner_id", string="Tests")
第一个参数称为comodel
,第二个参数是我们要倒数的字段。
按照惯例,One2many
字段具有_ids
后缀。它们作为记录列表的行为,这意味着必须访问数据必须以循环进行:
for test in partner.test_ids:
print(test.name)
危险
因为One2many
是一种虚拟关系,所以在comodel中必须定义Many2one
字段。
练习
添加房地产报价表。
- 创建
estate.property.offer
模型并添加以下字段:
字段 类型 属性 值 price Float status Selection no copy Accepted, Refused partner_id Many2one(res.partner) required property_id Many2one(estate.property) required - 创建树视图和表单视图,其中包含
price
、partner_id
和status
字段。无需创建动作或菜单。- 将字段
offer_ids
添加到您的estation.property
模型,并以本节目标中描述的形式添加。
这里有几件重要的事情需要注意。首先,我们不需要为所有模型提供动作或菜单。某些模型仅可通过另一个模型访问。在我们的练习中就是这样:要约总是通过房地产进行访问。
其次,尽管需要property_id
字段,但我们并未将其包括在视图中。Odoo如何知道我们的报价与哪个财产相关联?好吧,这是使用Odoo框架的魔力的一部分:有时事情是隐式定义的。当我们通过One2many
字段创建记录时,为了方便起见,相应的Many2one
会自动填充。
这一章绝对不是最容易的。它引入了一些新概念,同时依赖于之前引入的一切。下一章会更轻松,别担心;