近日,在Odoo(原OpenERP)中文开发者社区及GitHub Issue列表中,一则关于“osv/fields.py中html类继承错误”的技术讨论引发广泛关注。多名开发者反馈,在对Odoo 9版本进行模块开发或字段扩展时,尝试继承fields.html类会触发Python异常,导致模块无法正常安装或运行。该问题不仅影响已有模块向Odoo 9的迁移,也阻碍了新项目中对富文本字段的高级定制。
背景:Odoo 9 与 osv/fields.py 中的html字段
Odoo 9是Odoo公司于2015年底发布的重要版本,首次引入了全新的API(记录集、装饰器)并与旧版(osv)共存。在旧式API层(osv/fields.py)中,fields.html是用于存储富文本内容(如HTML格式的笔记、描述等)的字段类型。它继承自fields.text,并额外提供了HTML编辑器的支持(通过oe_html类或website.html前端控件)。许多企业模块依赖该字段来展示格式化内容,例如产品描述、邮件模板、合同条款等。
在Odoo 9中,尽管官方鼓励采用新API(odoo.fields.Html),但出于向后兼容和遗留模块的维护需求,osv/fields.py中的html类依然被广泛使用。问题正是出在这个“旧瓶装新酒”的过渡期。
错误现象:继承时出现NameError或属性缺失
根据开发者提供的错误堆栈,问题集中出现在以下场景:
- 在自定义模块中定义一个新类,尝试继承
osv.fields.html(例如class MyHtml(fields.html):)并重写其__init__或_check方法; - 在视图XML中引用该继承字段,或调用其
set、get方法处理数据; - 在服务器启动或模块升级时,Python解释器抛出
NameError: name 'html' is not defined,或AttributeError: 'module' object has no attribute 'html'。
进一步的追踪发现,osv/fields.py中html类的定义位于一个较晚的位置,并且依赖于fields模块中其他基类的初始化顺序。当开发者从外部导入并继承时,Python的类加载机制可能因为模块未完全初始化而找不到html类。更隐蔽的是,在Odoo 9的旧API框架下,fields.html类的_type属性(用于ORM映射)在某些情况下会被新API的Html字段覆盖,导致继承的子类无法正确注册。
影响范围:从模块移植到新项目开发
该Bug的影响并非个例。不少中文Odoo技术论坛的帖子显示,至少有三个主要场景受到波及:
- 模块从Odoo 8升级到9:Odoo 8中大量使用了
osv.fields.html的自定义子类(例如html_text、html_rich等),升级后直接继承会报错,开发者只能改写为新API的Html,但旧有的数据迁移逻辑需要额外处理。 - 前端模板扩展:部分模块为html字段定制了额外的CSS/JS控件,通过继承
html类来注入oe_html的options属性,如今面临重构。 - 第三方模块兼容性:一些流行的社区模块(如“website_blog”、“crm_lead_summary”)因依赖
osv.fields.html的继承特性,在Odoo 9社区版中表现出间歇性崩溃。
社区讨论:临时工作区与官方沉默
Odoo官方在GitHub(Odoo/odoo#14326等)上对该问题未给出直接修复,但开发者们通过调试总结出两种临时方案:
- 方案一:在模块的
__init__.py中显式导入osv.fields后再进行继承,例如from openerp.osv import fields,并确保自定义类定义在模块import之后。 - 方案二:放弃对
osv.fields.html的继承,改而直接创建新的fields.Html子类(新API),并手动设置旧API所需的_type、_class等属性,以兼容旧式视图渲染。
不过,这些方法均存在副作用:方案一可能导致模块加载顺序的硬依赖;方案二则要求开发者同时熟悉两套API,且无法保证对Odoo 9所有小版本的兼容性。
专家建议:迁移至新API是根本出路
瑞士Odoo技术顾问Thomas在开发者邮件列表中评论:“Odoo 9是一个分水岭,osv层已进入冻结期。继续在旧API上修补继承问题,相当于在沙子上盖楼。建议所有开发者在2025年之前将自定义模块完全迁移到新API,尤其是涉及html字段的场景——新API中的odoo.fields.Html已经内置了更安全的继承机制。”
国内Odoo资深开发者李明也表示:“此Bug暴露了Odoo 9过渡期框架层面的不完善。对于已投入生产的系统,可优先采用方案二临时解决;对于新项目,务必直接使用odoo.fields.Html,并通过sanitize和translate属性满足富文本处理需求。”
结语
尽管“osv/fields.py中html类继承错误”是一个具体的技术瑕疵,但它折射出Odoo版本迭代中API兼容性的阵痛。随着Odoo 10、11乃至当前16、17版本的普及,旧API终将被淘汰。但考虑到中文企业环境中仍有大量Odoo 9生产实例,这一问题值得社区持续关注并提供补丁。目前已有贡献者在Odoo官方仓库的维护分支(9.0)提交了修正PR,等待合并。对于每一位Odoo用户而言,及时跟进官方更新、主动迁移技术栈,才是避免类似Bug困扰的长久之计。