第十五章 Qweb
到现在为止,房地产模块的UI设计相当有限。创建list视图也是相当简单,只有fields列表是必须的。 Form视图也是这样,只用了几个标签比如group或者page,在UI设计上做的很少。
然而,如果我们想给我们的应用一个独一无二的设计,进一步学习设计新的视图是有必要的。还有,其他特性,像PDF报表或者网站页面也需要另外一种工具来创建,它提供了更多的灵活性:这就是模板引擎。templating engine.
你可能已经熟悉了现有的模板引擎,像Jinja(Python),ERB(ruby),或者Twig(PHP),Odoo内置了自己的引擎: QWeb Templates. Qweb是Odoo主要的模板引擎,它是一个XML模板引擎用来生成HTML片段或者页面。
你可能已经熟悉了 kanban board,其中的记录用类似卡片的结构显示,我们将为我们的房地产模块创建一个类似的视图
具体例子: A Kanban View
Reference: 参考文档 Kanban.
目标: 创建看板视图
在我们的房地产应用里,我们可以增加一个看板视图来显示房产。 看板视图是标准的Odoo视图(像form和list视图一样),但是他们的结构相当灵活,实际上,每个卡片的结构混合了表单元素(包括基本的HTML)和QWeb, 看板视图的定义也跟list视图类似,除了根元素是,最简单的看板视图,看上去是这样的
<kanban>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_global_click">
<field name="name"/>
</div>
</t>
</templates>
</kanban>
让我们解析一下这个例子:
<templates>
: 定义了 QWeb Templates 模板. 看板视图必须至少定义一个根模板kanban-box
, 对于每一条记录都会渲染一次。<t t-name="kanban-box">
:<t>
是QWEB的占位符,这里用来设置模板的名称为kanban-box
<div class="oe_kanban_global_click">
: theoe_kanban_global_click
让<div>
可以点击打开对应的记录<field name="name"/>
: 这是在视图中增加name字段
练习:
生成一个最小的看板视图
用上面的简单例子,为房地产模块生成一个最简单的看板视图,唯一的字段是name
Tip: 你必须在相应的ir.actions.act_window
.的 view_mode中增加kanban
一旦看板视图开始工作了,我们开始改进它,如果我们想有条件的显示某个元素,我们可以使用t-if(see Conditionals).
<kanban>
<field name="state"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_global_click">
<field name="name"/>
</div>
<div t-if="record.state.raw_value == 'new'">
This is new!
</div>
</t>
</templates>
</kanban>
我们加了一点新东西
t-if
: 如果条件为真,div会被渲染record
: 一个对象,请求的所有字段作为它的属性,每个字段有两个属性 value和raw_value , 前者会根据当前的用户参数格式化,而后者是直接的值from aread()
.
在上面的例子中,name字段像其他语言的模板引擎一样,python(Jinja),odoo也有自己的模板引擎Qweb
他基于xml,用来生成html页面和片段添加到了<templates>
元素中,但是state在外面,当我们需要一个字段的值但是不想在视图中显示的时候,就可以把它放在外边。
练习:
改进看板视图:
在看板视图中增加下列字段: expected price, best price, selling price and tags. 注意:the best price只有当收到报价才显示,而selling price只有当报价被接受才显示。
让我们对视图进行最后的润色: 默认情况下,房产必须按照类型进行分组,你可能想看一下不同的选项in Kanban.
练习:
增加默认分组
用合适的属性来分组房产,默认是房产类型,你也必须阻止卡片的拖拽。
看板视图是一个经典的例子,从现存的例子入手对它进行微调优化而不是从头开始,这永远是一个好主意。 有很多可用的选项和class,所以,read and learn
<record id="estate_property_view_kanban" model="ir.ui.view">
<field name="name">estate.property.kanban</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<kanban default_group_by="property_type_id" records_draggable="false">
<field name="state"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_global_click">
<group>
<h3> <field name="name"/> <field name="state"/> </h3>
expected_price :<field name="expected_price"/>
<t t-if="record.state == '1'">
<br/>
best_price:<field name="best_price" string="最优订单"/>
</t>
<t t-if="record.state == '2'">
<br/>
selling_price:<field name="selling_price"/>
</t>
<br/>
<field name="tag_ids" string="房屋标签" widget="many2many_tags"
options="{'color_field': 'color'}"/>
</group>
</div>
</t>
</templates>
</kanban>
</field>
</record>