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

如何在Create方法中更新One2many字段?遇psycopg2适配错误

Odoo中One2many字段赋值报错解决方案

问题描述

开发DownloadReport模型的create方法时,直接将santex.customer_auth等子记录集赋值给One2many字段,运行时报错:

psycopg2.ProgrammingError: can't adapt type 'santex.customer_auth'

原错误代码片段:

@api.model
def create(self, vals_list):
    recs_1 = self.env['santex.customer_auth'].create({'agency': vals_list["agency"]})
    recs_2 = self.env['santex.licensor_auth'].create({'agency': vals_list["agency"]})
    recs_3 = self.env['santex.certification_auth'].create({'agency': vals_list["agency"]})

    vals_list["customer_auth"] = recs_1
    vals_list["licensor_auth"] = recs_2
    vals_list["certification_auth"] = recs_3

    record = super(DownloadReport, self).create(vals_list)
    return record

错误原因

Odoo的One2many字段在create方法的vals参数中,不能直接赋值记录集对象,必须使用Odoo ORM规定的命令格式,或者先创建主记录再关联子记录。

解决方案

方案1:使用One2many命令语法(推荐)

One2many字段支持的命令格式为(6, 0, [ids]),其中6表示替换关联记录,0为固定参数,最后是子记录的ID列表。修改代码如下:

@api.model
def create(self, vals_list):
    # 创建子记录
    recs_1 = self.env['santex.customer_auth'].create({'agency': vals_list["agency"]})
    recs_2 = self.env['santex.licensor_auth'].create({'agency': vals_list["agency"]})
    recs_3 = self.env['santex.certification_auth'].create({'agency': vals_list["agency"]})

    # 用命令格式赋值One2many字段
    vals_list["customer_auth"] = [(6, 0, recs_1.ids)]
    vals_list["licensor_auth"] = [(6, 0, recs_2.ids)]
    vals_list["certification_auth"] = [(6, 0, recs_3.ids)]

    record = super(DownloadReport, self).create(vals_list)
    return record

方案2:先创建主记录,再关联子记录

利用子模型的inverse_name(即company_skills字段),先创建DownloadReport记录,再批量更新子记录的关联字段:

@api.model
def create(self, vals_list):
    # 先创建主记录(暂不设置One2many字段)
    record = super(DownloadReport, self).create(vals_list)
    
    # 创建子记录并关联到主记录
    self.env['santex.customer_auth'].create({'agency': record.agency.id, 'company_skills': record.id})
    self.env['santex.licensor_auth'].create({'agency': record.agency.id, 'company_skills': record.id})
    self.env['santex.certification_auth'].create({'agency': record.agency.id, 'company_skills': record.id})

    return record

如果是关联已存在的子记录(如补充信息中的recs_1 = [santex.customer_auth(75,), ...]),可以直接批量更新:

@api.model
def create(self, vals_list):
    record = super(DownloadReport, self).create(vals_list)
    
    # 关联已存在的子记录
    recs_1 = self.env['santex.customer_auth'].browse([75,76])
    recs_1.write({'company_skills': record.id})
    
    recs_2 = self.env['santex.licensor_auth'].browse([65,66])
    recs_2.write({'company_skills': record.id})
    
    recs_3 = self.env['santex.certification_auth'].browse([33])
    recs_3.write({'company_skills': record.id})

    return record

内容的提问来源于stack exchange,提问作者Selman Faruk Yılmaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:02:06