### 关系字段
关系领域的链接记录,无论是同一模型(层次结构),或不同型号。
关系字段类型:
[`Many2one(other_model, ondelete='set null')`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.Many2one "openerp.fields.Many2one")
一个简单的链接到另一个对象:
~~~
print foo.other_id.name
~~~
再者见
[外键](http://www.postgresql.org/docs/9.3/static/tutorial-fk.html)
[`One2many(other_model, related_field)`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.One2many "openerp.fields.One2many")
一个虚拟的关系,相反的 [`Many2one`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.Many2one "openerp.fields.Many2one"). 一个 [`One2many`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.One2many "openerp.fields.One2many") 作为记录的容器,访问它的结果在一个(可能是空的)组的记录:
~~~ python
for other in foo.other_ids:
print other.name
~~~
Danger
因为一个 [`One2many`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.One2many "openerp.fields.One2many") 是一个虚拟的关系, 那里 *必须* 是一个 [`Many2one`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.Many2one "openerp.fields.Many2one") 字段在 `*other_model*` 中, 还有它的名字 *必须* 是 `*related_field*`
[`Many2many(other_model)`](https://www.odoo.com/documentation/9.0/reference/orm.html#openerp.fields.Many2many "openerp.fields.Many2many")
双向多重关系,任何记录在一方可以与任何数量的记录在另一边。作为一个容器的记录,访问它也导致在一个可能是空的记录集:
~~~ python
for other in foo.other_ids:
print other.name
~~~
练习
Many2one 关系
使用many2one,修改 *Course* 和 *Session* 模型,以反映其与其他模型的关系:
* 有一个课程 *responsible* 用户; 该字段的值是内置模型的记录 `res.users`.
* 一个会话有一个 *instructor*; 该字段的值是内置模型的记录 `res.partner`.
* 一个会话与一个 *course*; 该字段的值是该模型的记录 `openacademy.course` 而且是必需的.
* 改变视图.
1. 添加相关 `Many2one` 字段的模型, 还有
2. 将它们添加到视图中.
*openacademy/models.py*
~~~ python
name = fields.Char(string="Title", required=True)
description = fields.Text()
responsible_id = fields.Many2one('res.users',
ondelete='set null', string="Responsible", index=True)
class Session(models.Model):
_name = 'openacademy.session'
~~~
~~~ python
start_date = fields.Date()
duration = fields.Float(digits=(6, 2), help="Duration in days")
seats = fields.Integer(string="Number of seats")
instructor_id = fields.Many2one('res.partner', string="Instructor")
course_id = fields.Many2one('openacademy.course',
ondelete='cascade', string="Course", required=True)
~~~
*openacademy/views/openacademy.xml*
~~~
<sheet>
<group>
<field name="name"/>
<field name="responsible_id"/>
</group>
<notebook>
<page string="Description">
~~~
~~~
</field>
</record>
<!-- 重写自动生成的列表视图 -->
<record model="ir.ui.view" id="course_tree_view">
<field name="name">course.tree</field>
<field name="model">openacademy.course</field>
<field name="arch" type="xml">
<tree string="Course Tree">
<field name="name"/>
<field name="responsible_id"/>
</tree>
</field>
</record>
<!-- window action -->
<!--
The following tag is an action definition for a "window action",
~~~
~~~
<form string="Session Form">
<sheet>
<group>
<group string="General">
<field name="course_id"/>
<field name="name"/>
<field name="instructor_id"/>
</group>
<group string="Schedule">
<field name="start_date"/>
<field name="duration"/>
<field name="seats"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- session tree/list view -->
<record model="ir.ui.view" id="session_tree_view">
<field name="name">session.tree</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<tree string="Session Tree">
<field name="name"/>
<field name="course_id"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="session_list_action">
<field name="name">Sessions</field>
<field name="res_model">openacademy.session</field>
~~~
练习
逆one2many关系
使用逆关系场one2many,修改模型以反映课程与课程之间的关系。
1. 修改 `Course` 类, 然后
2. 在课程表视图中添加该字段。
*openacademy/models.py*
~~~ python
responsible_id = fields.Many2one('res.users',
ondelete='set null', string="Responsible", index=True)
session_ids = fields.One2many(
'openacademy.session', 'course_id', string="Sessions")
class Session(models.Model):
~~~
*openacademy/views/openacademy.xml*
~~~ xml
<page string="Description">
<field name="description"/>
</page>
<page string="Sessions">
<field name="session_ids">
<tree string="Registered sessions">
<field name="name"/>
<field name="instructor_id"/>
</tree>
</field>
</page>
</notebook>
</sheet>
~~~
练习
多many2many关系
利用相关领域many2many,修改 *Session* 相关模型的每个会话的一套 *attendees* 。与会者将通过合作伙伴的记录为代表,所以我们将与内置的模型 `res.partner`。相应地调整意见。
1. 修改 `Session` 类, 然后
2. 在窗体视图中添加该字段。
*openacademy/models.py*
~~~ python
instructor_id = fields.Many2one('res.partner', string="Instructor")
course_id = fields.Many2one('openacademy.course',
ondelete='cascade', string="Course", required=True)
attendee_ids = fields.Many2many('res.partner', string="Attendees")
~~~
*openacademy/views/openacademy.xml*
~~~ xml
<field name="seats"/>
</group>
</group>
<label for="attendee_ids"/>
<field name="attendee_ids"/>
</sheet>
</form>
</field>
~~~