第三章 Reference字段的过滤

Reference字段是一种相对比较特殊的字段类型,它原生不支持Domain过滤,如果想要实现过滤则需要借助其他辅助工具。本文就将介绍如何使用context和name_search方法巧妙地间接地实现Reference的关联过滤效果。

Reference的问题

首先我们先来认识Reference的问题,我们知道Reference字段可以关联不同的数据模型,然后动态选择该数据模型下的数据记录,但是选择完数据模型以后,将显示该模型下的所有的数据记录。

如果尝试给Reference字段添加domain过滤,系统则会提示:

Domain on non-relational field "xxx" makes no sense (domain:[('parnter_id','=',False)])

也就是说,Reference字段不支持domain过滤。

解决方案

既然原生不支持,那么我们就需要通过其他方法间接实现此功能。首先我们知道Reference本质上是从Many2one字段继承而来,因此它原生支持name_get方法,既然我们希望在记录的选择中进行过滤,那么自然就可以使用name_search方法实现过滤。

这里的问题是,name_get方法针对于全局对象皆有效果,即你在某个对象上启用了name_search方法,那么对于系统中所有该模型的Many2one字段将同时生效,这可不是我们希望看到的。

这个时候,我们就可以通过field的context上下文对象传入一个特殊的值,在name_search方法中根据该值进行判断。

举例来说,我们在客户的某个项目中有个一Reference字段,关联了销售订单和线索两个对象

lead = fields.Reference(
        selection=[('sale.order', '销售订单'), ('crm.lead', '商机/线索')])

然后我们在字段的视图文件中添加一个上下文:

<field name="lead" required="1" domain="[('partner_id','=',partner_id)]" />

然后我们在name_search方法中进行判断区分

@api.model
def name_search(self,name,args=None,operator='ilike',limit=100):
    partner_id = self.env.context.get("partner_id",None)
    if partner_id is not None:
        args += [('partner_id','=',partner_id)]
    return super(sale_order,self).name_search(name,args,operator,limit)

由于我们只在特定的页面添加了context,而且partner_id是我们自定义的字段,因此这种方法可以避免绝大多数原生页面中的Many2one字段的冗余逻辑问题。

results matching ""

    No results matching ""