### 模型关联
[TOC]
一个模型中的记录可能关联到另一个模型中的记录。例如,销售订单记录会关联到一个包含客户数据的客户记录中;同时销售订单记录也会关联到销售订单明细记录。
> 练习建立一个授课模型
> 在开放学院模块中,我们考虑一个授课模型:一个授课是在给定的时间中对给定的受众教授指定的课程。为授课建立模型,授课包括名称、开始时间、持续时间和席位数。添加操作和菜单项来显示新的模型。
>
> * 在`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'
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`
~~~
<!-- Full id location:
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_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="session_menu" name="Sessions"
parent="openacademy_menu"
action="session_list_action"/>
</data>
</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`是一个虚拟关联,所以必须有一个`Many2one`字段存在于`other_model`,其名称也必须是`related_field`
`Many2many(other_model)`
双向多对多关联,一方的任一记录可以与另一方的任意数量记录关联。作为记录的容器,访问它也可能导致返回空记录集
~~~
for other in foo.other_ids:
print other.name
~~~
> 练习*Many2one*关联
> 编辑*Course*和*Session*模型以反映他们与其它模型的关联:
>
> * 课程有一个负责的用户;该字段的值是内置模型`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*
> 使用逆关联字段*one2many*,编辑模型以反映课程和授课之间的关系。
>
> * 编辑`Course`类,并且加入字段到它的表单视图
`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>
~~~
> 练习多对多关联*many2many*
> 在授课模型中添加关联字段*many2many*,将每次授课和参与的听众做关联,听众来自于内置模型`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>
~~~
作者:luohuayong
链接:http://www.jianshu.com/p/555a18060514
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 开发教程
- Odoo10开发教程一(构建模块)
- Odoo10开发教程二(基本视图)
- Odoo10开发教程三(模型关联)
- Odoo10开发教程四(继承)
- Odoo10开发教程五(计算字段和默认值)
- Odoo10开发教程六(高级视图)
- Odoo10开发教程七(工作流和安全)
- 参考手册
- odoo V10中文参考手册(一:ORM API)
- odoo V10中文参考手册(指导规范)
- 技巧
- odoo 常用widget
- Odoo(OpenERP)开发实践:菜单隐藏(1)
- Odoo(OpenERP)开发实践:菜单隐藏(2)
- Odoo(OpenERP)开发实践:数据模型学习
- Odoo中自动备份数据库
- Odoo(OpenERP)应用实践: 使用db-filter参数实现通过域名指定访问哪个数据库
- Odoo(OpenERP)配置文件openerp-server.conf详解
- Odoo(OpenERP v8)数据模型(Data Model)
- odoo10学习笔记十七:controller
- Qweb定义