模型之间的关系

一个模型的记录可以关联另一个模型的记录。例如,销售订单记录与包含客户数据的客户记录相关;客户记录也与其销售订单记录有关。

“创建学期模型”练习
我们考虑为“Open Academy”模块添加一个学期模型。学期是在给定时间针对给定观众讲授的课程的发生。
创建学期模型,学期具有名称、开始日期、持续时间和座位数。添加一个动作和一个菜单项,使新模型可见。

  1. openacademy/models/models.py中创建“Session”(学期)表。
  2. 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的记录,该值是必填的。
  • 调整视图。
  1. 向模型添加相关的Many2one字段。
  2. 在视图中添加它们。

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。相应地调整视图。

  1. 修改Session类,并
  2. 在表单视图中添加字段。

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>