模型之间的关系
一个模型的记录可以关联另一个模型的记录。例如,销售订单记录与包含客户数据的客户记录相关;客户记录也与其销售订单记录有关。
“创建学期模型”练习
我们考虑为“Open Academy”模块添加一个学期模型。学期是在给定时间针对给定观众讲授的课程的发生。
创建学期模型,学期具有名称、开始日期、持续时间和座位数。添加一个动作和一个菜单项,使新模型可见。
- 在
openacademy/models/models.py
中创建“Session”(学期)表。 - 在
openacademy/view/openacademy.xml
中添加学期的访问。
openacademy/models.py
name = fields.Char(string="Title", required=True)
description = fields.Text()
class Session(models.Model):
_name = 'openacademy.session'
_description = "OpenAcademy Sessions"
name = fields.Char(required=True)
start_date = fields.Date()
duration = fields.Float(digits=(6, 2), help="Duration in days")
seats = fields.Integer(string="Number of seats")
openacademy/views/openacademy.xml
action="openacademy.course_list_action"
It is not required when it is the same module -->
<!-- session form view -->
<record model="ir.ui.view" id="session_form_view">
<field name="name">session.form</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<form string="Session Form">
<sheet>
<group>
<field name="name"/>
<field name="start_date"/>
<field name="duration"/>
<field name="seats"/>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="session_list_action">
<field name="name">Sessions</field>
<field name="res_model">openacademy.session</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="session_menu" name="Sessions"
parent="openacademy_menu"
action="session_list_action"/>
</odoo>
digits=(6, 2)
指定浮点数的精度:6是数字的总数,而2是小数点后的数字。请注意,它导致小数点之前的数字位数最大为4。
关系字段
关系字段链接相同模型(层次结构)或不同模型之间的记录。
关系字段类型为:
Many2one(other_model, ondelete='set null')
“多对一”关系,与其他对象的简单链接:
print foo.other_id.name
One2many(other_model, related_field)
“一对多”关系,虚拟关系,Many2one
的逆向关系。One2many
表现为记录容器,访问它会产生一组记录(可能为空):
for other in foo.other_ids:
print other.name
由于
One2many
是虚拟关系,因此other_model
中必须有一个Many2one
字段 ,其名称必须为related_field
。
Many2many(other_model)
“多对多”关系,一侧的任何记录都可以与另一侧的任何数量的记录相关。表现为记录的容器,访问它会产生一组记录(可能为空):
for other in foo.other_ids:
print other.name
“Many2one关系”练习
使用Many2one,修改“课程”和“学期”模型以反映它们与其他模型的关系:
- 每个课程都有负责的用户;该字段的值是内置模型
res.users
的记录。 - 一个学期有一位老师; 该字段的值是内置模型
res.partner
的记录。 - 学期与课程有关; 该字段的值是模型
openacademy.course
的记录,该值是必填的。 - 调整视图。
- 向模型添加相关的Many2one字段。
- 在视图中添加它们。
openacademy/models.py
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'
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>
<!-- override the automatically generated list view for courses -->
<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,修改模型以反映课程和学期之间的关系。
1. 修改Course
类。
2. 在课程表视图中添加字段。
openacademy/models.py
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
<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>
“多个多对多关系”练习
使用多个关系字段,修改学期模型以将每个学期与一组参与者相关联。参加者将由合作伙伴记录代表,因此我们将涉及内置模型res.partner。相应地调整视图。
- 修改
Session
类,并 - 在表单视图中添加字段。
openacademy/models.py
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
<field name="seats"/>
</group>
</group>
<label for="attendee_ids"/>
<field name="attendee_ids"/>
</sheet>
</form>
</field>