卸载自定义模块后访问销售客户页面出现不存在字段错误
问题分析与解决方案
问题原因
你遇到的这个错误,核心原因是模块卸载后,数据库中res_partner表的is_commercial字段被移除,但系统中仍有引用该字段的配置残留——最常见的是用户保存的搜索过滤器(Search Filters)或者自定义视图里还保留着对这个字段的调用,当打开销售客户页面时,系统加载这些配置时找不到对应的字段,就会抛出这个ValueError。
你的模块代码本身逻辑是正常的,这里可以帮你简化下onchange方法的冗余判断:
from odoo import models, fields, api class Partner(models.Model): _inherit = 'res.partner' is_commercial = fields.Boolean(string= 'is Commercial') class User(models.Model): _inherit = 'res.users' is_commercial = fields.Boolean(string= 'is Commercial') @api.model def create(self, vals): user = super(User, self).create(vals) user.partner_id.active = user.active user.partner_id.is_commercial = user.is_commercial if user.partner_id.company_id: user.partner_id.write({'company_id': user.company_id.id}) return user @api.multi @api.onchange('is_commercial') def onchange_is_commercial(self): for partner in self.partner_id: partner.is_commercial = self.is_commercial
你卸载模块后遇到的错误信息:
File "D:\Projet\erp\odoo\osv\expression.py", line 821, in parse raise ValueError("Invalid field %r in leaf %r" % (left, str(leaf))) ValueError: Invalid field u'is_commercial' in leaf "<osv.ExtendedLeaf: (u'is_commercial', u'=', True) on res_partner (ctx: )>"
解决步骤
1. 清理残留的搜索过滤器(最常见原因)
- 登录Odoo后台,进入设置 > 技术 > 用户界面 > 搜索过滤器
- 在搜索框输入
res_partner,筛选出所有和客户相关的过滤器 - 检查每个过滤器的「域(Domain)」字段,找到包含
is_commercial的记录,直接删除这些过滤器
2. 检查并清理自定义视图
如果清理过滤器后问题仍存在,需要检查视图配置:
- 进入设置 > 技术 > 用户界面 > 视图
- 搜索
res_partner相关的视图,重点查看列表视图和搜索视图 - 找到包含
is_commercial字段的视图:如果是模块添加的继承视图,卸载后应该已自动删除;如果是手动修改的基础视图,需要编辑视图并移除对该字段的引用
3. 数据库层面直接清理(以上步骤无效时)
如果通过Odoo后台找不到残留配置,可以直接操作PostgreSQL数据库:
- 登录目标数据库:
psql -d 你的数据库名 -U 用户名 - 删除引用
is_commercial的搜索过滤器:DELETE FROM ir_filters WHERE model='res.partner' AND domain LIKE '%is_commercial%'; - 删除引用该字段的视图记录:
DELETE FROM ir_ui_view WHERE model='res.partner' AND arch_db LIKE '%is_commercial%'; - 执行完成后重启Odoo服务,再打开客户页面测试。
预防措施
为了避免后续出现类似问题,开发模块时可以注意:
- 尽量使用视图继承的方式添加字段,不要直接修改Odoo基础视图,这样模块卸载时继承视图会被自动清理
- 可以在模块中添加卸载钩子函数,主动清理可能残留的过滤器或配置:
def uninstall_hook(cr, registry): # 删除res_partner相关的is_commercial过滤器 cr.execute("DELETE FROM ir_filters WHERE model='res.partner' AND domain LIKE '%is_commercial%';")
内容的提问来源于stack exchange,提问作者Tessnim
相关产品推荐
相关产品推荐

