You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:09:10