4.5 将关系字段添加到模型

在Odoo模型中添加关系字段的全面解析

在Odoo开发中,模型之间的关系处理至关重要。关系字段能够有效地建立起不同模型之间的联系,使数据的组织和交互更加合理、高效。今天,我们就深入探讨如何在Odoo模型中添加关系字段。

一、关系字段类型概述

Odoo模型中的关系字段主要有三种类型:

(一)many-to-one(m2o)

表示多个记录关联到一个记录。例如,在宿舍管理系统中,一个房间属于一个宿舍,这种关系就是many-to-one,即多个房间关联到一个宿舍。

(二)one-to-many(o2m)

与many-to-one相反,一个记录可以关联多个其他记录。比如一个宿舍可以有多个房间,这就是one-to-many关系,从宿舍到房间的角度来看,一个宿舍对应多个房间。

(三)many-to-many(m2m)

表示多个记录可以与多个其他记录相互关联。例如,一个房间可以提供多种设施,同时一种设施也可以在多个房间中存在,这就是典型的many-to-many双向关系。

二、准备工作

在开始添加关系字段之前,我们需要做好相应的准备。首先,我们将继续使用前一个配方中的my_hostel附加模块。这个模块将作为我们操作的基础,为后续添加关系字段提供必要的环境和资源。

三、添加关系字段的步骤

(一)添加many-to-one(m2o)字段

  1. 打开models/hostel_room.py文件,在HostelRoom模型类中添加m2o字段hostel_id,用于关联宿舍。
class HostelRoom(models.Model):
    _name = "hostel.room"
    hostel_id = fields.Many2one("hostel.hostel", "hostel", help="Name of hostel")

这里,Many2one的第一个参数"hostel.hostel"指定了关联的目标模型,第二个参数"hostel"是字段在用户界面显示的名称,help参数提供了字段的帮助信息。

(二)创建one-to-many(o2m)字段

  1. 首先,我们需要为学生创建一个新模型。创建hostel_student.py文件,并添加一些基本字段到HostelStudent模型中,然后添加room_id m2o字段来连接学生和房间模型。
class HostelStudent(models.Model):
    _name = "hostel.student"
    name = fields.Char("Student Name")
    gender = fields.Selection([("male", "Male"), ("female", "Female"), ("other", "Other")], string="Gender", help="Student gender")
    active = fields.Boolean("Active", default=True, help="Activate/Deactivate hostel record")
    room_id = fields.Many2one("hostel.room", "Room", help="Select hostel room")
  1. 接着,在HostelRoom模型中添加o2m字段student_ids,用于关联学生模型。
class HostelRoom(models.Model):
    _name = "hostel.room"
    #...
    student_ids = fields.One2many("hostel.student", "room_id", string="Students", help="Enter students")

这里,One2many的第一个参数"hostel.student"指定了关联的目标模型,room_id指定了反向关联的字段。

(三)添加many-to-many(m2m)字段

  1. 创建hostel_amenities.py文件,添加HostelAmenities模型,包含基本字段。
class HostelAmenities(models.Model):
    _name = "hostel.amenities"
    _description = "Hostel Amenities"
    name = fields.Char("Name", help="Provided Hostel Amenity")
    active = fields.Boolean("Active", help="Activate/Deactivate whether the amenity should be given or not")
  1. HostelRoom模型中添加m2m字段hostel_amenities_ids,用于关联设施模型。
class HostelRoom(models.Model):
    _name = "hostel.room"
    #...
    hostel_amenities_ids = fields.Many2many("hostel.amenities", "hostel_room_amenities_rel", "room_id", "amenitiy_id", string="Amenities", domain="[('active', '=', True)]", help="Select hostel room amenities")

这里,Many2many的第一个参数"hostel.amenities"指定了关联的目标模型,"hostel_room_amenities_rel"是关系表的名称,room_idamenitiy_id分别指定了在关系表中与当前模型和目标模型关联的字段,domain参数用于筛选关联记录。

(四)升级模块并添加视图

完成上述字段添加后,升级附加模块,使新字段在模型中生效。然后,将新字段添加到hostel_room.xml文件中的视图定义中,这样新字段才能在用户界面中显示出来。

(五)确认字段添加

我们可以通过在开发者模式下进入Settings | Technical | Database Structure | Models,检查模型字段来确认关系字段是否成功添加。

四、关系字段的工作原理

(一)many-to-one(m2o)字段原理

  1. m2o字段在模型表中存储另一个记录的数据库ID,这会在数据库中创建一个外键约束,确保存储的ID是对另一个表中记录的有效引用。例如,hostel_id字段存储的是与之关联的宿舍记录的ID。
  2. 可以通过设置index=True属性为关系字段添加数据库索引,以提高查询性能。
  3. 对于m2o字段引用的记录被删除时的行为,可以通过ondelete属性进行控制。默认选项是'set null',即将字段设置为空值;'restrict'表示相关记录不能被删除;'cascade'则表示链接的记录也将被删除。

(二)one-to-many(o2m)字段原理

  1. o2m字段与m2o字段相反,它允许从一个模型访问相关记录的列表。但它在数据库表中没有实际的列,只是一种方便在视图中显示相关记录的方式。
  2. 要使用o2m字段,需要在另一个模型中有对应的m2o字段。例如,student_ids o2m字段通过room_id字段与HostelRoom模型建立关联。

(三)many-to-many(m2m)字段原理

  1. m2m字段在模型表中没有列,而是使用数据库中的另一个表来存储两个模型之间的关系。这个关系表有两列,分别用于存储相关记录的ID。当使用m2m字段关联房间和设施时,会在关系表中创建一条新记录,包含房间的ID和设施的ID。
  2. Odoo会自动为m2m字段创建关系表,默认名称由两个模型的名称按字母顺序排序后加上_rel后缀组成。如果两个模型名称过长,可以使用relation属性更改关系表名称。同时,要注意关系表的主键索引名称也有长度限制,如果默认名称超过限制,需要手动设置更短的名称。

(四)关系字段的其他属性

  1. context属性:主要在客户端使用,当点击字段查看相关记录视图时,它会在客户端上下文中设置一些变量。例如,可以用它为在该视图中创建的新记录设置默认值。
  2. domain属性:是一个过滤器,用于限制可以选择的相关记录列表。例如,在hostel_amenities_ids字段中,可以使用domain="[('active', '=', True)]"来只显示激活状态的设施。

五、注意事项与拓展

(一)注意事项

  1. 在处理m2o字段的auto_join属性时,虽然它可以让ORM使用SQL连接提高性能,但可能会跳过用户访问控制和记录访问规则检查,所以应谨慎使用,尽量避免使用该属性。
  2. 当处理相同两个模型之间的多个m2m字段时,必须为每个字段分配不同的关系表名称,以避免冲突。

(二)拓展阅读

关于关系字段的contextdomain属性的更多详细信息,可以参考第9章“Backend Views”。

你可能感兴趣的:(服务器,linux,python)