使用CRM模块修改Activity列非空的Lead阶段时触发ProgrammingError错误求助
解决
ProgrammingError: can't adapt type 'crm.activity' 错误 我之前在自定义CRM模块时也碰到过几乎一模一样的问题!这个错误本质是数据库驱动(比如psycopg2这类)没法把crm.activity类型的对象直接转换成数据库能识别的基础类型,大概率是你在Lead阶段变更的逻辑里,不小心把整个Activity对象赋值给了某个原本应该存ID、字符串或其他基础类型的字段,或者是ORM字段映射的配置出了问题。
下面是我当时排查和解决的几个核心方向:
1. 检查阶段变更的触发逻辑(代码/自动化动作)
不管你是通过重载模型的write方法、自定义工作流,还是低代码配置的自动化动作,重点看有没有以下错误:
- 比如在更新Lead阶段时,代码里写了类似
lead.some_field = activity_record的语句,但some_field其实是Integer(用来存Activity的ID)或者Char类型,而非关联crm.activity的字段。 - 如果你是用低代码配置的动作(比如CRM系统的自动化规则),检查是不是在字段赋值时误选了「活动对象」而非它的ID/名称等基础属性。
举个代码错误的例子(以Python CRM框架为例):
# 错误写法:把Activity对象直接赋值给非关联字段 def write(self, vals): # 获取一个Activity记录 activity = self.env['crm.activity'].browse(1) # 这里some_field是Integer类型,却赋值了整个对象 vals['some_field'] = activity return super(Lead, self).write(vals)
正确的写法应该是:
# 正确写法:赋值Activity的ID(如果字段是存ID的Integer类型) def write(self, vals): activity = self.env['crm.activity'].browse(1) vals['some_field'] = activity.id return super(Lead, self).write(vals) # 或者如果some_field是关联crm.activity的Many2one字段,直接传对象也可以(取决于框架支持) vals['activity_id'] = activity
2. 核对Lead模型的字段定义
检查你有没有新增和Activity相关的自定义字段,确认字段类型是否匹配:
- 如果你的字段是用来关联Activity记录的,应该定义成关联类型(比如
fields.Many2one('crm.activity')、ForeignKey(Activity)这类),而不是Integer、Char这类基础类型。 - 如果字段类型定义错误,ORM在保存数据时会尝试把Activity对象转换成字段对应的数据库类型,自然会抛出「无法适配类型」的错误。
3. 排查数据库层面的字段同步问题
如果你是自定义模块,且手动修改过数据库表的字段类型,或者模块升级时字段定义没有同步到数据库,也可能出现这个问题:
- 比如模型里定义的是关联字段,但数据库中对应的字段是
int类型,这时候赋值Activity对象就会触发类型适配错误。 - 可以通过查看数据库表结构,确认Lead表中相关字段的类型是否和模型定义一致。
4. 检查阶段变更时的信号/钩子函数
如果你的CRM框架支持信号或钩子(比如Django的signals),看看是不是在Lead阶段变更的钩子函数里,有错误的字段赋值逻辑,把Activity对象传给了不匹配的字段。
总结一下,这个错误最常见的根源就是**「类型不匹配」**:要么是把完整的Activity对象赋值给了非关联字段,要么是字段定义和实际存储的类型不一致。按照上面的步骤排查,应该很快能定位到问题。
内容的提问来源于stack exchange,提问作者Syarofan Zahroni
相关产品推荐
相关产品推荐

