1 2 3 4

9、模型之间的关联

一个模型的记录可能与另一个模型的记录有关。实际就是多张表中记录的关联方法

       例如,销售订单记录与包含客户数据的客户记录相关;它也与它的销售订单行项目记录有关。

       练习:创建一个会话模型

       我们考虑一个会话的模型:一个会话是在给定的时间给定的听众所教授的课程。

       为会话创建模型。会话有名称、开始日期、持续时间和多个位置。添加一个操作和一个菜单项来显示它们。通过菜单项使新模型可见。

 

#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")

注意:

   start_date = fields.Date(),Date类型,只能选择日期,Datetime类型是日期+时间的

digits=(6, 2)指定浮点数的精度:6是数字的总数,2是小数点的保留位数,注意在逗号之前的数字是4,加小数位数一共是6位

定义为表单视图:

        <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"/>

 关联字段

关联字段链接记录,同一模型(层次结构)或不同模型之间的任何一个。

关联字段类型有:

1、Many2one(other_model, ondelete='set null'):多对一

直接关联已经存在的表, 一个简单的链接到另一个对象:

取值方式为:

print foo.other_id.name

1)在models.py文件中为课程模块设置责任人,代码如下:

    responsible_id = fields.Many2one('res.users',
        ondelete='set null', string="Responsible", index=True)
res.users 指的是用户模块,是用户登陆信息表
ondelete='set null'  一旦用户表res.users被删除了,那么这个字段就会被设置为NULL
理解多对一:课程表内责任人是多个的,而用户表内的用户ID是唯一的

2)在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="教员")
    course_id = fields.Many2one('openacademy.course',
        ondelete='cascade', string="Course", required=True)
ondelete='cascade',串联模式,如果课程表openacademy.course中相关联的数据删除,那么Session表中的记录也会被删除。

将教员字段和res.partner表进行关联。

然后将Session模块中的课程和课程表进行关联,逻辑是:首先创建唯一的课程表,然后将每个学期的课程记录与课程表关联

注意:增加字段后,在视图View中tree类型和form类型中需要增加字段才能显示,否则字段显示不出来

如果需要增加数据需要重写模板数据

如下图:

 2、One2many(other_model, related_field)一对多

 一个虚拟的关系,是多对一反转的形式。One2many表现为记录的容器,其访问结果是记录集(可能是空的):

举例理解:课程表里面是唯一的,时间安排表中的记录多次用到课程表。那么通过课程表反查时间安排表中就会有多条记录。

取值方式为:

for other in foo.other_ids:
    print other.name

警告:因为One2many是一种虚拟关系,所以在other_model必须要有一个Many2one的字段,并且它的名字必须是related_field

 例如:

1)修改models.py中的Course 类

2)在form视图中增加字段

    session_ids = fields.One2many(
        'openacademy.session', 'course_id', string="Sessions")
                            <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>

 如下图:

session表中的记录:

Course表中语文课程的显示:

 3、Many2many(other_model) 多对多的关系

双向多重关系,任何一方的记录都能与另一方的多条记录关联,作为记录的容器,访问它也会可能导致空记录集。

练习:

多重多对多关系

使用关系字段多对多,修改Sessin模块为每一个课程关联参与者,参与者被设置为合作伙伴记录,所以我们将关联到内置模块res.partne,并改写相应的视图。

1、修改Session类

2、添加字段到表单视图

    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")
                                <field name="seats"/>
                            </group>
                        </group>
                        <label for="attendee_ids"/>
                        <field name="attendee_ids"/>
                    </sheet>
                </form>
            </field>

 

多对多,在数据库中会添加一张关系表,如下图:

从下图可以看出关系表的命名规则:第1张表的表名_第2张表的表名_rel

说明rel结束的都是自动生成的多对多的关系表

 

 

 

 

理解多对一、一对多、多对多:

1、多对一,当前表是多条的,关联表数据为唯一的。例如:时间安排表中的课程是重复的,课程表中的课程是唯一的

2、一对多,是多对一的反向。例如:时间安排表中有很多条记录对应语文课程,那么根据语文查询时间安排表,就对有多条数据

3、多对多,从一个表中关联另一个表是多条的,从另一个表关联本表也是多条的。例如:课程安排表关联参与人员

 

posted @ 2018-04-30 21:58  I我的博客I  阅读(405)  评论(0)    收藏  举报