第四章 QWeb

首先我们需要知道QWeb是什么, QWeb是odoo用来渲染HTML的模板引擎, 类似于Jinjia2之于Django. QWeb引擎的标志就是使用t-开头的控制语句.下面我们来详细学习一下QWeb模板引擎的相关知识.

输出与控制

开始总是最简单,我们先认识一个最简单的QWeb模板:

<t t-if="condition">
    <p>Test</p>
</t>

这个例子非常简单, 如果condition表达式的结果为True, 那么

Test

就会被渲染出来,否则什么也不会输出.

数据输出

如果我们希望在某个元素中输出一个表达式的值, 那么可以使用t-esc表达式:

<p><t t-esc="value"/></p>

如果value的值是html并且希望保留原格式输出,那么可以使用t-raw替代

<t t-raw="address">

逻辑控制 t-if

如果我们希望在某个元素中判断一个表达式的值, 那么可以使用t-if表达式:

<t t-if="condition">
    <p>Test</p>
</t>

循环遍历 t-foreach

QWeb也支持循环遍历:

<p t-foreach="[1, 2, 3]" t-as="i">
    <t t-out="i"/>
</p>
<t t-foreach="[1, 2, 3]" t-as="i">
    <p><t t-esc="i"/></p>
</t>

t-as 将每次迭代的值传给变量i,方便后续的调用。

这里有多个内置的变量(以i为例):

  • i_all: 迭代的对象
  • i_value: 迭代对象的值,一般情况下和i的值相同,但是当迭代字典时,i为key,i_value为字典的值
  • i_index: 序列
  • i_size: 迭代列表的长度
  • i_first: 列表的第一个值
  • i_last: 列表的最后一个值
  • i_parity: 当前迭代的奇偶性
  • i_even: 当前迭代是否为偶数
  • i_odd: 当前迭代是否为奇数

字段输出 t-field

如果想要输出odoo中某个模型的字段值, 那么可以使用t-field表达式:

<td>
    <span t-field="ml.product_id.display_name"/><br/>
    <span t-field="ml.product_id.description_picking"/>
</td>

那么 t-esc与 t-field有何区别?

t-esc用于输出数据,其值为python表达式执行完的结果。t-field 只能用于字段的访问,且只对存储的字段有效。另外,t-field-options可用于格式化字段值。例如:

<t-field="o.date" t-field-options='{"widget":"date"'}'/>

赋值变量 t-set

如果想要在QWeb自定义变量, 则可以选择t-set:

<t t-set="existing_variable" t-value="False"/>

属性操作

qweb中也可以操作html中的元素的属性值。

t-att-$name

t-att-$name用于创建动态的属性名:

<div t-att-name="42">

将创建一个拥有name属性值为42的节点:

<div name="42">

输出图片

如果我们想要在QWeb中输出图片,可以使用image_data_uri方法:

<img t-att-src="image_data_uri(order.image)" t-if="order.image" style="width:80px"/>

image_data_uri输出的是base64字符串,如果想要链接的形式则可以使用/web/image连接来完成。

<img t-att-src="/web/image?id=8&amp;&model='sale.order'&map;field=image_1920" t-if="order.image" style="width:80px"/>

t-attf-$name

t-attf-$name与t-att-$name类似,区别在于t-attf-$name输出的是格式化的字符串:

<t t-foreach="[1, 2, 3]" t-as="item">
    <li t-attf-class="row false ? 'even' : 'odd' ">
        <t t-out="item"/>
    </li>
</t>

输出:

<li class="row even">1</li>
<li class="row odd">2</li>
<li class="row even">3</li>

数据的格式化

货币格式化

对应货币的金额精度,可以使用format_currency方法来格式化货币的精度:

<td class = "pos-right-align"> 
    <t-esc = "widget.format_currency (taxdetail.amount)" /> 
</ td>

浮点类型与货币类型的转换

如果我们的字段本身就是货币类型,那么不需要使用转换,即可显示成2,000$这种形式的数据。

而如果是整形或者浮点型,那么我们可以使用t-options将其转换成货币类型

<span t-field="doc.amount_undiscounted" t-options="{&quot;widget&quot;: &quot;monetary&quot;, &quot;display_currency&quot;: doc.pricelist_id.currency_id}"/>
  • widget: 使用moentary部件
  • display_currency: 指定货币字段。

如果想要控制货币精度,则需要到货币设置里改变它的精度值。

如果想要在Qweb中使用货币类型但同时又不想显示货币符号,那么需要配合我们的基础模块来完成:

<span t-field="line.price_unit" t-options="{'symbol':False}"/>

使用symbol设置成False来去除货币符号。

浮点数精度控制

对于浮点数的精度控制,我们可以使用t-options来协助我们:

<span t-out="line.amount_tax"  t-options='{"widget": "float", "precision": 2}'/>

继承

基础的QWeb继承与之前的xml的写法都不一样,首先不需要odoo标签的包裹,另外不同于普通的模板,基础模板的写法需要使用templates标签包裹。

例如,我们给Many2one的部件添加一个前缀12345,可以这么写:

<templates>
    <t t-extend="FieldMany2One">
        <t t-jquery=".o_field_many2one" t-operation="before">
            <a>123456</a>
        </t>
    </t>
</templates>

t-extend用于扩展Qweb的内容,配合t-operation可以实现xml中position类似的效果,具体来说,t-operation有以下几种值可以选择:

  • append: 节点的主体被附加在上下文节点的末尾(在上下文节点的最后一个子节点之后)
  • prepend: 节点的主体被添加到上下文节点(在上下文节点的第一个子节点之前插入)
  • before: 节点的主体被插入在上下文节点之前
  • after: 节点的主体被插入在上下文节点之后
  • inner: 节点的主体替换上下文节点的子节点
  • replace: 该节点的主体用于替换上下文节点本身

t-jquery指令采用一个CSS selector。此选择器用于扩展模板以选择应用指定的t-operation的上下文节点。

如果使用t-extend,odoo会要求你必须写入一个t-jquery选择器,如果想要使用replace的本身节点话,就会冲突。此时,你应该选择放弃使用t-extend,而使用同名的t-name将原有的代码覆盖掉,就像python的后定义的方法会覆盖掉前面定义的方法一样。

另外,如果想要完全重写某个QWeb部件,那么可以不用上面提到的几种操作,直接简单粗暴的定义一个同名的QWeb部件即可,后加载的部件会覆盖掉之前定义的部件。

  1. Qweb的继承视图不能设置组权限,否则会引起异常
  2. 在Qweb中还有一类叫做Qweb Fields的伪字段类型, 称它为伪字段类型,是因为虽然它顶着fields的名字却不存储在数据库中,只是在Qweb中作为中转站使用.这类字段的作用是将记录中的某些字段,转化为HTML片段嵌入到Qweb报表中.关于这部分的内容, 我们等到第五部分时会详细探讨。
  3. OWL Qweb的继承与传统的QWeb继承语法不同,我们在QWeb介绍时会详细说明。

results matching ""

    No results matching ""