odoo学习模型关系与复杂字段
3月11日 生死族投稿 一般关系字段的命名规则是在模型的后面加上id或ids,以用来区分多对一或一对多,下图为多对一和多对多的关系字段:
下图为一对多的关系字段:
1、many2one的关系:
many2one在本例中使用了两个位置参数,第一个是与本模型关联的另一个模型的名称,可以使用参数关键字comodel直接赋值;第二个是本关系字段的描述,可以使用参数关键字string直接赋值。当我们在模型中使用该方法声明一个关系字段时,后台数据库会生成一个外键字段。
除了上面介绍的两个参数之外,该类型还包含其他几个可用参数,具体如下。ondelete:该参数定义了删除关联记录时本字段的动作,默认是setnull,也就是说当关联记录被删除时本字段将被赋值为空。第二个可以赋予的值是restricted,若设置该值则关联记录被删除时会报错进而阻止关联字段被删除。还有一个可选值是cascade,使用本值时关联字段若被删除则本记录也将被删除。context:该参数是对前端使用具有实际意义的数据字典,用于在进行关系导航时携带信息,比如设置默认值。domain:这是一个域表达式,在一个队列中可以使用元组设定查询条件以用于限定查询的数据。autojoin:该参数可用于帮助ORM引擎在执行查询时进行一个SQL关联。如果使用,则其将会绕过访问安全规则,用户可以访问权限以外的数据,这将造成很大的风险,不过这样做可以让数据查询更加灵活。
2、many2many关系:
many2many类型在使用的时候其实可以很简洁,最少只需要一个关联模型名称的参数。不过一般建议加上string描述参数。
与many2one一样,多对多也支持domain和context两个属性。
在数据库层面,两个多对多关系的模型都不会增加字段。Odoo是通过自动增加第三个关系表来专门维护两个模型的关系。这个关系表中就包含了两个字段,分别存放两个模型里面记录的ID字段中。默认情况下,这个关系表的名称是两个模型表的名称用下划线连接并且在后面加上rel的后缀,因为这种规则,可能会出现关系表名过长的问题。
里有两种方法来指定关系表名称:位置参数方式和关键字参数。
位置参数的方式,示例如下:
第2行指定了管理模型的名称。第3行就是我们自己命名的关联表的名称。第4行定义了存储本模型关联字段的字段名称。第5行定义了存储关联模型关联字段的字段名称。第6行是本字段的描述标签。
需要注意的是,如果在抽象模型中使用了这种制定表名和列名的方式建立多对多关系,则抽象模型不可再被继承,这是ORM引擎的限制,使用时需要注意,不要在抽象模型中使用这种方式。
关键字参数,示例如下:
可以看出这种方式的可读性要更强,所以更推荐这种使用方式。
many2many的逆向关系也是many2many,比如我们在bm。bug。tag模型中的那种使用方式,只是写了两个参数。Odoo会自动识别这个多对多与bm。bug模型里面的many2many类型的字段是同一个many2many关系,使用的是同一个关系表。
3、one2many的逆向关系
many2one关系的逆向关系就是one2many(onetomany),可以为many2one关系的另一端的关联模型增加one2many字段,这样并不会影响实际的底层数据库表,真正的数据还是记录在多(many)一方的底层表中。不过one2many字段可以让另一端获取数据更为方便,比如示例中bm。bug。stage模型可以通过bugids方便地获取处于一个阶段的所有bug。
我们在使用的时候通过位置参数的方式使用了前面两个参数,对应的参数关键字就是comodelname和inversename。
除了以上几个参数之外,还支持context、domain和ondelete三个参数关键字。
4、层级结构关系
除了在不同的模型之间具有many2one、one2many等关系之外,同一个模型也可以有这种关系。这种模型的数据记录之间具有层次结构,父记录与子记录之间是one2many的关系,子记录与父记录之间是many2one的关系。
具体操作起来,就是使用模型中的parentstore模型属性,并且使用parentleft和parentright两个字段作为辅助,示例如下:
5、使用引用字段的动态关系
在常规的关系字段的使用中,可通过属性comodel来确定关联关系的两个模型。在引用字段类型中则不需要使用该属性,而且引用字段支持动态的关联关系,也就是说同一个字段可以引用多个模型。
例如,在bm。bug模型中增加一个bug发现者字段,可以是用户或伙伴,示例代码如下:
引用字段的定义与Selection类型比较相似,第一个参数是一个包含元组的列表,第二个参数是一个描述。在前端的使用上,用户首先选择bug发现者是用户还是合作伙伴,然后再从对应的模型里面选择记录。计算字段
字段中可以使用根据函数自动计算所得的类型,计算字段的声明方式与常规字段是一样的,只是使用了compute参数,参数被赋值为一个函数的名称。比如:
投诉 评论