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

Odoo API批量更新One2Many字段仅更新单条数据问题求助

Odoo API批量更新问题排查与解决

问题描述

为Web应用开发Odoo API时遇到批量更新异常:客户端传入包含product_char为A、M的两条数据,但数据库中仅更新了M对应的petty.cash.line数据。尝试过update和write方法均无效,已提供控制器代码、petty.cash.app与petty.cash.line的One2Many/Many2one关联字段定义。

客户端传入JSON示例:

[{"product_char": "A", "quantity": "1", "price_unit": "100"},
{"product_char": "M", "quantity": "1", "price_unit": "100"}]

控制器关键代码片段:

petty_cash_line = request.env['petty.cash.line'].sudo().search([('pety_cash_id', '=', petty_cash.id)])
for product in eval(rec['products']):
    petty_cash_line.update({
        'pety_cash_id': petty_cash.id,
        'product_char': product['product_char'],
        'quantity': product['quantity'],
        'price_unit': product['price_unit'],
    })

问题原因

  1. 集合更新覆盖问题:search返回的是所有匹配pety_cash_id的petty.cash.line记录集合,循环中直接对整个集合调用update,每次循环都会把所有匹配记录替换为当前product的数据,最终只有最后一条(M)的更新会保留。
  2. 未定位单条记录:代码没有根据product_char匹配到具体要更新的单条记录,导致批量更新变成了多次全量覆盖。

解决方案

方案1:匹配单条记录精准更新

修改循环逻辑,每次根据product_char和pety_cash_id定位到具体记录后再更新,不存在则可选新增:

for product in json.loads(rec['products']):  # 替换eval,避免安全风险
    # 定位对应单条记录
    line = request.env['petty.cash.line'].sudo().search(
        [
            ('pety_cash_id', '=', petty_cash.id),
            ('product_char', '=', product['product_char'])
        ],
        limit=1
    )
    if line:
        line.write({
            'quantity': product['quantity'],
            'price_unit': product['price_unit'],
        })
    else:
        # 可选:记录不存在时新增
        request.env['petty.cash.line'].sudo().create({
            'pety_cash_id': petty_cash.id,
            'product_char': product['product_char'],
            'quantity': product['quantity'],
            'price_unit': product['price_unit'],
        })

方案2:通过One2Many字段批量操作(推荐)

如果petty.cash.app模型中有指向petty.cash.line的One2Many字段(如line_ids),可利用Odoo ORM的批量操作格式,一次性完成更新和新增:

line_vals = []
for product in json.loads(rec['products']):
    line = request.env['petty.cash.line'].sudo().search(
        [
            ('pety_cash_id', '=', petty_cash.id),
            ('product_char', '=', product['product_char'])
        ],
        limit=1
    )
    if line:
        # (1, 记录ID, 更新值):更新已有记录
        line_vals.append((1, line.id, {
            'quantity': product['quantity'],
            'price_unit': product['price_unit'],
        }))
    else:
        # (0, 0, 新增值):创建新记录
        line_vals.append((0, 0, {
            'pety_cash_id': petty_cash.id,
            'product_char': product['product_char'],
            'quantity': product['quantity'],
            'price_unit': product['price_unit'],
        }))

# 主模型批量写入One2Many字段
petty_cash.write({'line_ids': line_vals})

注意事项

  • 禁止使用eval处理客户端JSON,改用json.loads避免代码注入风险。
  • 检查pety_cash_id字段拼写是否与模型定义一致,拼写错误会导致搜索不到目标记录。

内容的提问来源于stack exchange,提问作者Bian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:42:59