如何使用函数字段的store参数?

1 投票
1 回答
3319 浏览
提问于 2025-04-18 17:52

我试着去看了一下文档,但是有点搞不懂。

另外,store这个东西能用在其他类型的字段上吗?

1 个回答

11

先回答第二个问题:relatedsparse 这两个字段都是 function 的子类,所以 store 可能可以和它们一起使用,但我还没有尝试过。


store 参数的意思是告诉 OpenERP 是否可以记住并保存调用函数的结果,以避免再次调用。

接下来我们看看它是怎么工作的,以下是一个例子:

    'order_status': fields.function(
        _order_status,
        type='char',
        method=True,
        store= . . . ,
        string='Order Status',
        ),

默认情况下,storeFalse,这意味着每次请求记录时,函数字段都会被重新计算。

不过,还有两个其他可能的值——True 或一个 dicttuple

        store=True,

True 很好理解,简单来说就是这个值会被计算一次,然后存储起来,之后每次记录变化时都会重新计算。

        store={
            'model.table': (function, ['field1', 'field2', ...], priority),
            'another_model.table': (some_func, [], priority),
            },

dicttuple 有点复杂,但功能很强大。通过它,我们可以告诉 OpenERP 什么时候需要重新计算这个字段。

字典的键是表名,比如 res.partnerproduct.product;三元组中的第一个项目是要调用的函数,第二个项目是要监控的键表中的字段列表,最后一个项目是处理函数的优先级或顺序,如果有多个函数的话1

下面是一个例子:

        store={
            'product.product': (_get_product_dependent_ids, ['name','price'], 20),
            'res.partner': (_get_partner_dependent_ids, ['login'], 10),
            },

从后往前看,优先级(每个元组的最后一个项目)告诉我们 res.partner 的元组会先运行,因为它的优先级较低。

中间的项目是要监控的字段列表:对于 res.partner,OpenERP 会监控 login 字段,每当 login 字段发生变化时,OpenERP 就会调用 _get_partner_dependent_ids;同样,每当 product.product 记录的 nameprice 字段发生变化时,OpenERP 会调用 _get_product_dependent_ids2

元组中的第一个项目是要调用的函数,这部分有点棘手。这个函数的签名是:

def _get_ids(key_table, cr, uid, ids_of_changed_records, context=None):

注意,key_table 不是 self 即使这个函数可能是你依赖类中的一个方法(比如 custom.table1),第一个参数不是那个表,而是存储字典中列为键的表——在我们的例子中是 product.productres.partner3

这个函数应该做什么呢?它应该返回一个列表,包含你自定义表中需要重新计算该字段的所有记录的 ID。

这是我的函数字段:

    'order_status': fields.function(
        _order_status,
        type='char',
        method=True,
        store={
            'fnx.pd.order': (_get_schedule_ids_for_order, ['state'], 20),
            },

这是我的存储函数:

def _get_schedule_ids_for_order(fnx_pd_order, cr, uid, ids, context=None):
    if not isinstance(ids, (int, long)):
        [ids] = ids
    return [s.id for s in fnx_pd_order.browse(cr, uid, ids, context=context).schedule_ids]

字段定义告诉我们,每当 fnx.pd.order 中的记录的 state 字段发生变化时,_get_schedule_ids_for_order 将会被调用,并传入那些 state 字段发生变化的 fnx.pd.order 记录的 ID。

_get_schedule_ids_for_order 会查找变化的记录,获取相关的日程记录的 ID,并返回它们。


脚注:

  1. priority 字段会对表中每个字段的每个 _get_ids() 函数进行排序,而不仅仅是单个函数的 _get_ids()。这在一个函数字段依赖于另一个函数时非常有用。

  2. 如果字段列表为空,那么对任何字段的修改都会导致函数被调用。

  3. 如果你需要在函数内部访问自己的表,可以这样做:

    self = key_table.pool.get('my_module_name_here.my_table_name_here')
    

撰写回答