17. QWeb简介
到目前为止,房地产(estate)模块的界面设计还比较有限。构建列表视图非常简单,因为只需要列出字段列表即可。表单视图也是如此:尽管使用了<group>或<page>等少数标签,但在设计方面几乎无需费心。
然而,若想让应用程序呈现独特的外观,就必须更进一步,能够设计新的视图。此外,PDF 报表或网站页面等其他功能也需要另一种工具来实现,以获得更大的灵活性:即模板引擎。
一些开发者可能已经熟悉现有的模板引擎,例如 Jinja(Python)、ERB(Ruby)或 Twig(PHP)。Odoo 自带内置引擎:QWeb 模板。QWeb 是 Odoo 主要使用的模板引擎。它是一个 XML 模板引擎,主要用于生成 HTML 片段和页面。
前面已经在 Odoo 中见过看板(kanban board),其中记录以卡片式结构显示。接下来将继续房地产模块构建一些视图。
看板视图
本节学习目标:创建一个属性看板视图。视图效果如下图所示:

在房产应用中,希望添加一个看板视图来展示房产信息。看板视图是 Odoo 的一种标准视图(与表单视图和列表视图类似),但其结构要灵活得多。实际上,每张卡片的结构都是表单元素(包括基础 HTML)与 QWeb 的混合体。看板视图的定义与列表视图和表单视图的定义类似,区别仅在于其根元素是 <kanban>。在最简单的形式下,看板视图如下所示:
<kanban>
<templates>
<t t-name="card">
<div>
<field name="name"/>
</div>
</t>
</templates>
</kanban>下面来分析一下这个示例:
<templates>:定义了一组 QWeb Templates 模板。看板视图必须至少定义一个根模板 card,该模板将针对每条记录渲染一次。<t t-name=“card”>:<t>是 QWeb 指令的占位符元素。在此处,它用于将模板名称设置为card;<field name="name"/>:这将向视图中添加name字段。
开发实践:创建一个简易看板视图
利用提供的简单示例,为“属性”创建一个简易看板视图。仅显示“name”字段。
提示:须在相应的
ir.actions.act_window的view_mode中添加kanban。
当看板视图正常运行,我们就可以开始对其进行优化。如果需要根据条件显示某个元素,可以使用 t-if 指令(参见“[条件语句](QWeb Templates — Odoo 19.0 documentation)”)。
<kanban>
<field name="state"/>
<templates>
<t t-name="card">
<div>
<field name="name"/>
<div t-if="record.state.raw_value == 'new'">
This is new!
</div>
</div>
</t>
</templates>
</kanban>在上面示例代码中,添加了以下内容:
t-if:如果条件为真,则渲染<div>元素。record:一个包含所有请求字段作为属性的对象。每个字段都有两个属性:value和 raw_value。前者根据当前用户参数进行格式化,后者则是read()函数返回的原始值。
在上例中,字段名称被添加到了 <templates> 元素内,但 state 位于该元素之外。当我们需要某个字段的值,但又不希望在视图中显示它时,可以将该字段添加到 <templates> 元素之外。
开发实践:改进看板视图
在看板视图中添加以下字段:预期价格、最佳价格、成交价格和标签。请注意:最佳价格仅在收到报价时显示,而成交价格仅在报价被接受时显示。
为视图做最后的润色:默认情况下,属性应按类型分组。可以参考[看板](View architectures — Odoo 19.0 documentation)中介绍的各种选项。
开发实践:添加默认分组
使用相应的属性,默认按类型对属性进行分组。此外,还必须禁止拖放操作。
看板视图是一个典型的例子,可以从现有视图示例开始并进行微调,总比从零开始要好。可用的选项和类有很多,所以……请仔细阅读并学习吧!