近日,在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中引用该继承字段,或调用其setget方法处理数据;
  • 在服务器启动或模块升级时,Python解释器抛出NameError: name 'html' is not defined,或AttributeError: 'module' object has no attribute 'html'

进一步的追踪发现,osv/fields.pyhtml类的定义位于一个较晚的位置,并且依赖于fields模块中其他基类的初始化顺序。当开发者从外部导入并继承时,Python的类加载机制可能因为模块未完全初始化而找不到html类。更隐蔽的是,在Odoo 9的旧API框架下,fields.html类的_type属性(用于ORM映射)在某些情况下会被新API的Html字段覆盖,导致继承的子类无法正确注册。

影响范围:从模块移植到新项目开发

该Bug的影响并非个例。不少中文Odoo技术论坛的帖子显示,至少有三个主要场景受到波及:

  1. 模块从Odoo 8升级到9:Odoo 8中大量使用了osv.fields.html的自定义子类(例如html_texthtml_rich等),升级后直接继承会报错,开发者只能改写为新API的Html,但旧有的数据迁移逻辑需要额外处理。
  2. 前端模板扩展:部分模块为html字段定制了额外的CSS/JS控件,通过继承html类来注入oe_htmloptions属性,如今面临重构。
  3. 第三方模块兼容性:一些流行的社区模块(如“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,并通过sanitizetranslate属性满足富文本处理需求。”

结语

尽管“osv/fields.py中html类继承错误”是一个具体的技术瑕疵,但它折射出Odoo版本迭代中API兼容性的阵痛。随着Odoo 10、11乃至当前16、17版本的普及,旧API终将被淘汰。但考虑到中文企业环境中仍有大量Odoo 9生产实例,这一问题值得社区持续关注并提供补丁。目前已有贡献者在Odoo官方仓库的维护分支(9.0)提交了修正PR,等待合并。对于每一位Odoo用户而言,及时跟进官方更新、主动迁移技术栈,才是避免类似Bug困扰的长久之计。