“多对多关系”的版本间的差异
来自Odoo大V社-odoo中文开发手册
2355481564(讨论 | 贡献) |
|||
第44行: | 第44行: | ||
'todo.task', # related model | 'todo.task', # related model | ||
string='Tasks') | string='Tasks') | ||
+ | |||
+ | 上一节:[[多对一关系]] 下一节:[[一对多反向关系]] |
2017年5月4日 (四) 05:55的版本
Many2many 最少要提供一个参数,也就是关联的模块,建议使用string参数,以便更好的标题展示。
在数据库层面,数据库表中是不会添加任何字段。它会自动的创建一个新的中间表,这个表只有两个外键ID字段,并且这两个字段分别关联对应的数据库表。这个中间表和字段的名字都是自动生成的。中间表的名字是两个表的名字用下划线拼接后在加上_rel组成的。
有时候,我们可能需要改变这种自动的默认值。
其中的一种情况就是,关联的模块有很长的名字,那么自动生成的中间表的名称就会很长,可能会超出PostgreSQL对于表名不得多于63个字符的限制。这种情况下,我们就需要手动选择一个不超出限制的名字。
另一种情况,在相同的模块中需要两个many2many的关系。这种情况,我们也需要手动的为中间表添加名称,只有这样,才能避免数据库名称冲突。
有两种方式去手动的设置这些值:按位置传值或指定参数名传值
使用按位置传值的方式,字段的定义如下:
# Task <-> Tag relation (positional args): tag_ids = fields.Many2many( 'todo.task.tag', # related model 'todo_task_tag_rel', # relation table name 'task_id', # field for "this" record 'tag_id', # field for "other" record string='Tags')
- 注意
这些位置参数都是可选的。我们可以只设置中间表的名称,而让它的字段名称自动生成。
我们也可以使用指定参数名称的方式赋值,那样更具有可读性:
# Task <-> Tag relation (keyword args): tag_ids = fields.Many2many( comodel_name='todo.task.tag', # related model relation='todo_task_tag_rel', # relation table name column1='task_id', # field for "this" record column2='tag_id', # field for "other" record string='Tags')
和many2one字段相似,many2many字段也可以定义domain和context等关键属性
- 注意
目前,由于ORM的局限性,对于抽象模块(Abstract models),当强制命名中间表的名称和列名称后,它们就不能被继承修改了。所以对于抽象模块,请谨慎使用。
Many2many相反的关系也是Many2many。如果我们为Tags模块添加了一个Many2many的字段,ODOO会判定,在Task模块中就会存在一个相反的many2many关系。
在Tags模块中,与Tasks相反的关系可以如下定义:
class Tag(models.Model): _name = 'todo.task.tag' # Tag class relationship to Tasks: task_ids = fields.Many2many( 'todo.task', # related model string='Tasks')
上一节:多对一关系 下一节:一对多反向关系