第八章 父子表
前面的章节中覆盖了给模型创建自定义视图,并包含基本的字段。可是,在任何真实的场景中我们需要不止一个模型。而且,模型之间的连接是必要的。
可以很容易的想象,一个模型包含客户,另一个模型包含用户列表。 你可能需要在现存的商业模型中引用一个客户或者一个用户。
在我们的房地产模块中,我们需要关于房地产的下列信息:
- 购买了房产的客户
- 售出房产的销售代表
- 房产类型: house, apartment, penthouse, castle…
- 描述房产的标签列表: cozy, renovated…
- 收到的订单的列表 a list of the offers received
Many2one
参考:关于这个主题的文档在这里 Many2one
.
目标: 在这一小节结尾:
- 新建
estate.property.type
模型并增加相应的菜单、动作和视图
- 三个 Many2one 字段应该被加到estate.property模型中, property type, buyer and seller.
在我们的房地产模块中,我们想定义房产类型的概念。 房产类型就是类似于公寓或者别墅,这是一个标准的商业需求来给房产分类,根据他们的类型,特别是当调优过滤条件的时候。
一处房产可以有一个类型,但是同样的类型可以赋值给多处房产,这通过many2one的概念来支持。
many2one 是一个简单的链接指向另一个对象,比如,为了定义一个链接指向res.partner,我们可以这样写:
partner_id = fields.Many2one("res.partner", string="Partner")
通常来说,many2one字段都带这_id后缀,可以很容易的访问partner中的数据
print(my_test_object.partner_id.name)
See also
在实际中,many2one在form视图中被渲染成一个下拉列表。
练习: 增加estate.property.type
模型,并增加下列字段:
Field | Type | Attributes |
---|---|---|
name | Char | required |
- 按照本章节的目标增加菜单
- 在estate.property模型以及它的form,tree和search视图中增加property_type_id
这个练习是对前几个章节的很好的复习,你需要新建模型,设置模型,增加action和菜单以及增加视图。
tip: 别忘了在 __init__.py
文件中引入新的python文件,在清单文件中引入新的数据文件,并且增加存取权限。
然后,重启服务并刷新浏览器就看到结果了。
在房地产模块中,依然有两个信息没有添加到房产模型中: 购买房产的客户和销售代表。 购买房产的客户可以是任何独立的个人,但是销售代表必须是房地产模块的雇员,也就是Odoo user。
在odoo中,有两个模块我们要引用:
res.partner
: partner 是一个物理的或者逻辑的实体,它可以是一家公司,一个个人甚至是一个地址。res.users
: 系统用户,可以是内部用户 ‘internal’,也就是说可以登录Odoo后台.或者是门户 ‘portal’,也就是说他们不能登录后台,但是可以登录前台 (访问他们的商业订单).
练习:增加买房人和销售代表
给 estate.property 模型增加买房人和销售代表,用之前提到的res.partner和res.user,在form视图中增加一个新的tab页面展示他们。
销售代表的默认值必须是当前用户,买房人不应该能复制。
Tip: 为了获取默认值,检查下面的笔记或者查看这个例子 here.
Note
The object self.env
gives access to request parameters and other useful things:
self.env.cr
orself._cr
is the database cursor object; it is used for querying the databaseself.env.uid
orself._uid
is the current user’s database idself.env.user
is the current user’s recordself.env.context
orself._context
is the context dictionaryself.env.ref(xml_id)
returns the record corresponding to an XML idself.env[model_name]
returns an instance of the given model
现在让我们来看看其他类型的链接。
Many2many
参考:关于这个主题的文档在这里 Many2many
.
目标: 在这一小节的结尾:
- 创建一个新的estate.property.tag 模型以及相应的菜单和动作。
estate.property
模型中增加标签
在我们的房地产模块中,我们想定义房产标签的概念,一个房产标签,例如,东边套,拎包入住,临街房等。。
一处房产可以有多个标签同时一个标签也可以赋值给多处房产,这就是多对多的概念。
many2many是一种双向多重关系:一端的任何记录都可以与另一端的任意数量的记录相关联。例如,为了定义到帐户的链接。在我们的测试模型上,我们可以写:
tax_ids = fields.Many2many("account.tax", string="Taxes")
一般来说,many2many字段都有_ids的后缀,这意味着,多个taxes可有增加到我们的测试模型,它表现为一个记录列表,意味着要通过循环来存取数据。
for tax in my_test_object.tax_ids:
print(tax.name)
记录列表称之为记录集,也就是有顺序的记录集。 它支持标准的python集合操作,例如len(),iter(), 其他的一些操作 recs1 | recs2 ?(这是啥操作?)
练习:增加estate.property.tag 并增加下列字段
Field | Type | Attributes |
---|---|---|
name | Char | required |
- 增加相应的菜单
- 在estate.property以及对应的form和tree视图中 中增加tag_ids字段
Tip: 在视图中,use the widget="many2many_tags"
widget将在后续的章节中学习 a later chapter of the training,现在,你可以尝试增加或者删除widget看看效果。
One2many
参考:关于这个主题的文档在这里 One2many
.
Goal:
- 新建一个新的
estate.property.offer
模型以及对应的form和tree视图 - estate.property 增加 offers
我们的房地产模块中,我们想定义房产报价的概念,一个房产报价是一个潜在客户报给卖方的金额,报价可以高于或者低于期待的价格。
一个报价只能应用到一处房产,但是同一处房产可以有多个报价。 多对一的概念再次出现了,然而在这种情况下我们想展示给定房产的报价列表,所以我们使用一对多的概念。
一对多跟多对一相反,例如,我们定义了我们的测试模型通过partner_id连接到res.partner 模型,我们可以定义相反的关系,也就是说test模型的列表到我们的partner。
test_ids = fields.One2many("test.model", "partner_id", string="Tests")
第一个参数叫做comodel,第二个参数就是我们想反向关联的字段
通常来说,一对多字段有_ids后缀,他们像一组记录列表,意味着必须通过循环来存取数据。
for test in partner.test_ids:
print(test.name)
危险
因为一对多字段是一种虚拟的关系,所以必须要先在comodel中定义多对一字段。
练习:增加estate.property.offer
模型,加入下列字段
Field | Type | Attributes | Values |
---|---|---|---|
price | Float | ||
status | Selection | no copy | Accepted, Refused |
partner_id | Many2one (res.partner ) | required | |
property_id | Many2one (estate.property ) | required |
- 创建树形视图和form视图,其中包含字段price,partner_id和status ,没必要创建动作或者菜单。
- estate.property 模型中增加
offer_ids
并且 在form视图中展示出来。
这里有几件重要的事情需要注意:
1、我们没必要为所有的模型创建动作或者菜单,一些模型只能通过其他模型来访问,我们这个练习的案例,报价永远通过房产来访问。
2、其次,尽管’ property id '字段是必需的,但我们没有在视图中包含它。Odoo如何知道我们的报价与哪个房产相关?这就是使用Odoo框架的神奇之处:有时候东西是隐式定义的。当我们通过one2many字段创建记录时,为了方便起见,会自动填充相应的many2one。
还活着码? 这一章绝对不是最简单的一章,它介绍了几个新的概念,同事依赖之前介绍的所有内容,下一章会轻松点,别担心;-)