
本文详解如何在 Odoo 16 中为 one2many 行内的进度条(ProgressBar)创建自定义字段组件,并基于计算字段或配置选项动态设置背景色,解决 Missing widget 错误及模板继承问题。
本文详解如何在 odoo 16 中为 one2many 行内的进度条(progressbar)创建自定义字段组件,并基于计算字段或配置选项动态设置背景色,解决 `missing widget` 错误及模板继承问题。
在 Odoo 16 中,web.basic_fields.FieldProgressBar 已被重构为基于 OWL 的 @web/views/fields/progress_bar/progress_bar_field.js,因此旧式继承方式(如 require('web.basic_fields'))将失效,并导致浏览器报错:Missing widget: CustomProgressBar for field of type integer。正确做法是使用模块化 OWL 语法继承官方进度条字段,并通过模板覆盖与属性注入实现动态样式。
✅ 正确继承方式(Odoo 16+)
首先,创建 JavaScript 文件(如 static/src/js/custom_progressbar_field.js),使用标准 Odoo 模块声明语法:
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { ProgressBarField } from "@web/views/fields/progress_bar/progress_bar_field";
export class CustomProgressBarField extends ProgressBarField {}
// 注册为新字段类型
registry.category("fields").add("custom_progressbar", CustomProgressBarField);⚠️ 注意:必须使用 /** @odoo-module **/ 声明,且路径需在 __manifest__.py 的 assets 中正确引入:
"assets": {
"web.assets_backend": [
"your_module_name/static/src/js/custom_progressbar_field.js",
"your_module_name/static/src/xml/custom_progressbar_template.xml",
],
},? 动态着色方案一:基于记录字段值(推荐)
假设你在 transient model 的 one2many 行中定义了一个计算字段 color_code(如 'bg-success', 'bg-warning', 'bg-danger'),可直接在模板中通过 t-attf-class 绑定:
static/src/xml/custom_progressbar_template.xml
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="web.CustomProgressBarField" t-inherit="web.ProgressBarField" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('o_progress')]/div" position="attributes">
<attribute name="t-attf-class">
o_progress_value
{{ props.record.data.color_code or 'bg-primary' }}
h-100
</attribute>
</xpath>
</t>
</templates>并在 Python 模型中定义该字段(例如):
color_code = fields.Char(compute="_compute_color_code", store=False, readonly=True)
def _compute_color_code(self):
for rec in self:
if rec.progress < 30:
rec.color_code = "bg-danger"
elif rec.progress < 70:
rec.color_code = "bg-warning"
else:
rec.color_code = "bg-success"视图中使用:
<field name="line_ids">
<tree editable="bottom">
<field name="progress" widget="custom_progressbar"/>
<!-- color_code 是 invisible 计算字段,无需显式显示 -->
</tree>
</field>? 动态着色方案二:支持字段级颜色配置(高级用法)
若需为不同进度条字段指定不同颜色字段(如 status_color 或 priority_color),可通过 options 传参并扩展 extractProps:
custom_progressbar_field.js(增强版)
export class CustomProgressBarField extends ProgressBarField {}
CustomProgressBarField.template = "chn_event_availability_manager.custom_progressbar_template";
CustomProgressBarField.props = {
...ProgressBarField.props,
colorField: { type: String, optional: true },
};
CustomProgressBarField.extractProps = ({ attrs }) => {
const parentProps = ProgressBarField.extractProps({ attrs });
return {
...parentProps,
colorField: attrs.options?.color_field || "color_code",
};
};
registry.category("fields").add("custom_progressbar", CustomProgressBarField);对应 XML 模板(支持 HEX 颜色值)
<t t-name="chn_event_availability_manager.custom_progressbar_template" t-inherit="web.ProgressBarField" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('o_progress')]/div" position="attributes">
<attribute name="t-att-style">
width: min(100 * state.currentValue / state.maxValue + '%', 100%);
background-color: {{ props.record.data[props.colorField] || '#007bff' }} !important;
</attribute>
</xpath>
</t>视图中按需传参:
<field name="progress" widget="custom_progressbar" options="{'color_field': 'status_color'}"/>⚠️ 关键注意事项
- 不要混用旧版 API:避免 require('web.basic_fields') 或 field_registry,Odoo 16+ 全面转向 @web/core/registry 和 OWL。
- 模板继承必须带 owl="1":否则 XPath 不生效;t-inherit-mode="primary" 确保完全替换原模板节点。
- CSS 类优先级:若 Bootstrap 类(如 bg-danger)未生效,检查是否被 .o_progress_value 默认样式覆盖,可加 !important 或调整 CSS specificity。
- 性能提示:color_code 等计算字段建议设为 store=False, readonly=True,避免写入数据库,仅用于前端渲染。
通过以上步骤,你即可在 Odoo 16 的 one2many 行中稳定、灵活地实现进度条颜色动态绑定,兼顾可维护性与扩展性。

















