### 模型關聯
[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定義