今天这个案例是属于python的业务代码,先交待一下业务场景。
我们的业务数据有时候需要从Excel文件中导入,其中有一列是客户名称,在导入的时候需要判断客户名称在res.partner模型中是否存在。早期的代码是这样子写的:
for row in range(1, excel_rows):row_data = sh.row_values(row)partner_obj = self.env['res.partner'].search([('name','=',row_data[2])])if not partner_obj:raise except_orm('error','客户名称不存在')......
这个for循环里面的判断逻辑其实有很多,这里我只是取了一个例子。当Excel记录比较多的时候,这个循环执行得比较慢,我们在优化的时候,发现针对客户的判断,不需要每次都从数据库查询,相同的客户名称只要检查一次就可以了,于是我们就改为了下面这样子:
@api.model@tools.ormcache(skiparg=0)def get_partner(self, name):return self.env['res.partner'].search([('name', '=', name)]).....for row in range(1, excel_rows):row_data = sh.row_values(row)partner_obj = self.get_partner(row_data[2])if not partner_obj:raise except_orm('error','客户名称不存在')......
这里把客户的获取逻辑重构为一个单独的方法,并且用到了ormcache进行缓存,这样如果参数相同的时候,odoo直接从内存返回上一次的结果,而不会重新调用search方法。
修改后实际操作的过程中,又发现一个新问题,第一次导入数据,提示客户不存在。然后在客户模型录入了新的客户。第二次导入时,因为使用了缓存,调用get_partner方法时,它不会重新从数据库获取新的记录,所以还是会提示客户不存在。这里就需要我们再修改一个地方:
@api.model@tools.ormcache(skiparg=0)def get_partner(self, name):return self.env['res.partner'].search([('name', '=', name)]).....self.env['res.partner'].clear_cache()for row in range(1, excel_rows):row_data = sh.row_values(row)partner_obj = self.get_partner(row_data[2])if not partner_obj:raise except_orm('error','客户名称不存在')......
在循环之前,加一个clear_cache方法,把原来的缓存清除,这样第二次导入时就不会继续沿用第一次的缓存结果。
这里要注意的是在定义需要缓存结果的方法时,方法不能定义为api.multi装饰的方法。
文章转载自Odoo哥,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




