“多对多关系”的版本间的差异

来自Odoo大V社-odoo中文开发手册
跳转至: 导航搜索
(创建页面,内容为“Many2many 最少要提供一个参数,也就是关联的模块,建议使用string参数,以便更好的标题展示。 在数据库层面,数据库表中是...”)
 
 
(未显示2个用户的2个中间版本)
第1行: 第1行:
 
Many2many 最少要提供一个参数,也就是关联的模块,建议使用string参数,以便更好的标题展示。
 
Many2many 最少要提供一个参数,也就是关联的模块,建议使用string参数,以便更好的标题展示。
  
在数据库层面,数据库表中是不会添加任何字段。它会自动的创建一个新的关联数据库表,这个表只有两个外键ID字段,并且这两个字段分别关联对应的数据库表。这个关联数据库表和字段的名字都是自动生成的。关联数据库的名字是两个表的名字用下划线拼接后在加上_rel组成的。
+
在数据库层面,数据库表中是不会添加任何字段。它会自动的创建一个新的中间表,这个表只有两个外键ID字段,并且这两个字段分别关联对应的数据库表。这个中间表和字段的名字都是自动生成的。中间表的名字是两个表的名字用下划线拼接后在加上_rel组成的。
  
 
有时候,我们可能需要改变这种自动的默认值。
 
有时候,我们可能需要改变这种自动的默认值。
  
其中的一种情况就是,关联的模块有很长的名字,那么自动生成的关联数据库表名就会很长,可能会超出PostgreSQL对于表名不得多于63个字符的限制。这种情况下,我们就需要手动选择一个不超出限制的名字。
+
其中的一种情况就是,关联的模块有很长的名字,那么自动生成的中间表的名称就会很长,可能会超出PostgreSQL对于表名不得多于63个字符的限制。这种情况下,我们就需要手动选择一个不超出限制的名字。
  
另一种情况,在相同的模块中需要两个many2many的关系。这种情况,我们也需要手动的为关系数据库添加名称,只有这样,才能避免数据库名称冲突。
+
另一种情况,在相同的模块中需要两个many2many的关系。这种情况,我们也需要手动的为中间表添加名称,只有这样,才能避免数据库名称冲突。
  
 
有两种方式去手动的设置这些值:按位置传值或指定参数名传值
 
有两种方式去手动的设置这些值:按位置传值或指定参数名传值
第20行: 第20行:
 
     string='Tags')
 
     string='Tags')
 
*注意
 
*注意
  这些位置参数都是可选的。我们可以只设置关系数据库的名字,而让它的字段名称自动生成。
+
  这些位置参数都是可选的。我们可以只设置中间表的名称,而让它的字段名称自动生成。
 
我们也可以使用指定参数名称的方式赋值,那样更具有可读性:
 
我们也可以使用指定参数名称的方式赋值,那样更具有可读性:
 
  # Task <-> Tag relation (keyword args):
 
  # Task <-> Tag relation (keyword args):
第33行: 第33行:
 
*注意
 
*注意
  
  ORM有一个限制,对于抽象模块(Abstract models),如果你自定义了关系数据库名和字段名,他们就不能被清除数据。所以不能对抽象模块做这种操作。
+
  目前,由于ORM的局限性,对于抽象模块(Abstract models),当强制命名中间表的名称和列名称后,它们就不能被继承修改了。所以对于抽象模块,请谨慎使用。
  
 
Many2many相反的关系也是Many2many。如果我们为Tags模块添加了一个Many2many的字段,ODOO会判定,在Task模块中就会存在一个相反的many2many关系。
 
Many2many相反的关系也是Many2many。如果我们为Tags模块添加了一个Many2many的字段,ODOO会判定,在Task模块中就会存在一个相反的many2many关系。
  
在Tags模块中,与Tasks相反的关系可以如下定义:
+
在Tag模块中,与Tasks相反的关系可以如下定义:
 
  class Tag(models.Model):
 
  class Tag(models.Model):
 
     _name = 'todo.task.tag'
 
     _name = 'todo.task.tag'
第44行: 第44行:
 
         'todo.task', # related model
 
         'todo.task', # related model
 
         string='Tasks')
 
         string='Tasks')
 +
 +
上一节:[[多对一关系]] 下一节:[[一对多反向关系]]

2018年5月9日 (三) 13:32的最新版本

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关系。

在Tag模块中,与Tasks相反的关系可以如下定义:

class Tag(models.Model):
    _name = 'todo.task.tag'
    # Tag class relationship to Tasks:
    task_ids = fields.Many2many(
        'todo.task', # related model
        string='Tasks')
上一节:多对一关系 下一节:一对多反向关系