Odoo15运行采购协议自定义代码报String index out of range错误
问题根因
String index out of range报错是Odoo ORM的search方法domain参数格式错误直接触发的,除此之外代码还有3处逻辑错误会导致功能异常,具体问题点:
- 直接触发报错的问题:
search()方法要求传入的domain参数是「条件元组组成的列表」,你写的['id', '=', 'purchase_agreement_id']把三个独立字符串直接放在列表里,没有包裹成(字段名, 操作符, 匹配值)格式的元组,ORM解析domain规则时会遍历字符串取对应位置的字符,直接触发索引越界。 - 匹配值逻辑错误:你给id条件传的是字符串字面量
'purchase_agreement_id',就算domain格式写对,也是在搜索id等于这个字符串的采购协议记录,完全匹配不到目标数据,实际应该取当前记录上purchase_agreement_id字段关联的记录ID作为匹配值。 - 行数据赋值错误:创建明细行的vals里
product_id传的是line.id,这个值是采购协议明细行本身的记录ID,不是关联的产品ID,正确取值应为line.product_id.id,否则会生成产品关联完全错误的明细行。 - 缩进逻辑错误:
rec.line_ids = lines的缩进位置在if rec.purchase_agreement_id判断外,当关联采购协议不存在时会直接清空当前记录的所有明细行,不符合业务预期。
修复后代码
# 字段定义(原有模型关联关系无问题可保留) purchase_agreement_id = fields.Many2one('purchase.requisition', string='Purchase Agreement Id') # 方法实现 def purchase_agreement(self): # 修正domain格式,正确传入关联记录的ID作为匹配值 for rec in self.env['purchase.requisition'].search([('id', '=', self.purchase_agreement_id.id)]): lines = [] if rec.purchase_agreement_id: for line in rec.purchase_agreement_id.line_ids: vals = { 'product_id': line.product_id.id, # 修正:取明细行关联的产品ID 'description': line.product_description_variants, 'quantity': line.product_qty, } lines.append((0, 0, vals)) # 修正缩进:仅在拿到有效协议行时才给明细字段赋值,避免误清空数据 rec.line_ids = lines
补充提示:如果该方法是定义在采购订单等调用采购协议的业务模型上,完全不需要额外调用search,直接通过
self.purchase_agreement_id就能拿到关联的采购协议记录,多余的search操作反而可能因为记录集上下文问题取错数据。
内容的提问来源于stack exchange,提问作者MohammadAliChamass
相关产品推荐
相关产品推荐

