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'], })
问题原因
- 集合更新覆盖问题:
search返回的是所有匹配pety_cash_id的petty.cash.line记录集合,循环中直接对整个集合调用update,每次循环都会把所有匹配记录替换为当前product的数据,最终只有最后一条(M)的更新会保留。 - 未定位单条记录:代码没有根据
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
相关产品推荐
相关产品推荐

