如何在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
相关产品推荐
相关产品推荐

