odoo 过滤器域运算符 "child_of" 的解释及其对 "in" 运算符的偏好

explanation of odoo filter domain operator "child_of" and its preference over "in" operator

在阅读文档和使用 child_of 运算符而不是使用 in 运算符进行过滤后,我不确定 child_of 做了什么

可以找到 Odoo v10 域文档 here,其中说明 child_of

的以下内容
is a child (descendant) of a value record.
Takes the semantics of the model into account (i.e following the relationship field named by _parent_name)

考虑模型 product.product 有一个名为 pos_categ_id 的 many2one 字段指向模型 pos.category

只获取 PoS 类别 ID 为 x 的产品,可以使用域值 ['pos_categ_id', 'child_of', x],但是 ['pos_categ_id', 'in', [x]] 似乎也可以做同样的事情。

除此之外,in 运算符可用于格式与上述示例相同的 many2many 和 one2many 字段,而对这两种字段类型使用 child_of 运算符会导致错误。

示例域 ['session_ids', 'child_of', [572]] 其中 session_ids 是一个 many2many 字段导致以下错误 Invalid field 'parent_id' in leaf \"<osv.ExtendedLeaf: ('parent_id', 'in', [572]) on pos_session (ctx: )>\"

那么,child_of 优于 in 运算符的示例情况是什么?除了 in 可以在所有类型的关系字段上工作外,两者的功能似乎相同。其次,child_of 文档的第二行中短语 following the relationship field named by _parent_name 是什么意思?

基本上 child_of 功能由 odoo 提供,而不是 python。

但要理解它,您必须了解 parent、数据库概念中的“子”关系。

如果您的任何表正在使用 自连接,如下例所示。

_name = 'my.table'

parent_id = fields.Many2one('my.table', string='Parent Id')

在上述情况下,您的模型已自行连接。在 Odoo 中的这种情况下,您可以在域中使用 child_of 运算符。

因此,它将在数据库中搜索 parent_id = <your_value>

对于in域,

您可以在id字段中传递您需要搜索的数据列表。它类似于任何数据库 in 运算符。

不,它们不一样,是的,它们在您使用的简单示例中是相同的:

To only get products with PoS category id of x, domain value of ['pos_categ_id', 'child_of', x] can be used, however ['pos_categ_id', 'in', [x]] seems to also do the same thing.

但考虑这种情况:

#               x                
#              / \               
#             f   b                
#                / \               
#               c   d  

当我们这样做时 ['pos_categ_id', 'child_of', x] 这将 return 其类别是此列表之一的产品 [x, f, b, c, d] 它等同于 ['pos_categ_id', 'in', [x, f, b, c, d]]。 因为它们都是 x 的 child(child_of 包括 x 本身).

但这:['pos_categ_id', 'in', [x]] 将 return 仅产品其类别为 X 但不会 return 类别为 b or c ..etc 的产品。

要在您的自定义模型中激活此功能,您应该设置此属性

  class YourModel(models.Model):
     _name = 'some.model'
     _parent_name = 'parent_id'  # by default its name is parent_id you can change it
     _parent_store = True  # tell odoo that this model support parent & child relation ship

     # same name of _parent_name 
     parent_id = fields.Many2one('some.model', 'Parent')
class Partner(models.Model):
    _name = 'res.partner'
    _parent_name = 'parent_partner_id'  # the many2one field used as parent 
    _parent_store = True

    parent_partner_id = fields.Many2one('res.partner', store=True)        
    parent_path = fields.Char(index=True)