第十章 Odoo 12开发之后台视图 – 设计用户界面
本文为最好用的免费ERP系统Odoo 12开发手册系列文章第十篇。
本文将学习如何为用户创建图形化界面来与图书应用交互。我们将了解不同视图类型和小组件(widgets)之间的差别,以及如何使用它们来提供更优的用户体验。
本文主要内容有:
- 菜单项
- 窗口操作(Window Actions)
- 表单视图结构
- 字段
- 按钮和智能按钮
- 动态视图元素
- 列表视图
- 搜索视图
- 其它视图类型
开发准备
我们将继续使用library_checkout插件模块,它已经有了模型层,现在需要视图层来实现用户界面。本文中的代码基于第八章 Odoo 12开发之业务逻辑 - 业务流程的支持,相关代码请参见 GitHub 仓库,本章完成后代码也请参见 GitHub仓库。
菜单项
用户界面的入口是菜单项,菜单项形成一个层级结构,最顶级项为应用,其下一级为每个应用的主菜单。还可以添加更深的子菜单。可操作菜单与窗口操作关联,它告诉客户端在点击了菜单项后应执行什么操作。
菜单项存储在ir.ui.menu模型中,可通过Settings > Technical > User Interface > Menu Items菜单进行查看。
library_app模块为图书创建了一个顶级菜单,library_checkout插件模块添加了借阅和借阅阶段的菜单项。在library_checkout/views/library_menu.xml文件中,借阅的菜单项 XML 代码如下:
1 | <menuitem id="menu_library_checkout" |
这里有一个
- name是展示在用户界面中的菜单项标题
- action是点击菜单项时运行的窗口操作的XML ID
- parent是父级菜单项的XML ID。本例中父级项由其它模块创建,因此们使用了完整的XML ID,
. 进行引用。
还有以下可用属性:
- sequence设置一个数字来在展示菜单项时进行排序,如sequence=”10”
- groups是一个逗号分隔的可访问菜单项安全组的XML ID列表,如groups=”library_app.library_group_user, library_app.library_group_manager”
- web_icon是菜单项的图标,仅用于企业版的顶级菜单项,如web_icon=”library_app,static/description/icon.png”
窗口操作(Window Actions)
窗口操作给 GUI(图形化用户界面)客户端操作指令,通常用于菜单项或视图中的按钮。它告诉 GUI 所作用的模型以及要显示的视图。这些操作可以通过域过滤器过滤出可用记录,设置默认值以及从上下文属性中过滤。窗口操作存储在ir.actions.act_window模型中,可通过Settings > Technical > Actions > Window Actions菜单进行查看。
在library_checkout/views/library_menu.xml文件中,我们可以找到借阅菜单项中使用的窗口操作,我们需要对其进行修改来启用本文中将添加的视图类型:
1 | <act_window id="action_library_checkout" |
窗口操作通常像以上这样使用
- name是通过操作打开的视图中显示的标题
- res_model是目标模型的标识符
- view_mode是一个逗号分隔的可用视图类型列表。第一项为默认打开时的视图。
窗口操作还有一些其它属性:
- target:如果设置为 new,会在弹出的对话框窗口中打开视图,例如target=”new”。默认值是current,在主内容区行内打开视图。
- context:为目标视图设置上下文信息,可设置默认值或启用过滤器等,例如context=”{‘default_user_id’: uid}”。
- domain:是对可在打开视图中浏览的记录强制过滤的域表达式,例如domain=”[(‘user_id’, ‘=’, uid)]”。
- limit:列表视图中每页显示的记录数,例如limit=”80”。
做了这些修改后,在选择Checkouts菜单项并浏览相应的列表视图时,右上角在列表和表单按钮后会增加一些按钮。但在我们创建对应视图前并不能使用,本文将一一学习。窗口操作还可在列表和表单视图的上方的 Action 菜单按钮中使用,它在 Fitlers 按钮旁。要使用这个,我们需要在元素中添加以下两个属性:
- src_model设置Action所作用的模型,例如src_model=”library.checkout”
- multi=”true”也启用列表视图中的Action,这样它可以作用于多个已选记录。否则仅在表单视图中可用,并且一次只能应用于一条记录。
补充:此时打开借阅表单会提示Insufficient fields for Calendar View!,在编写日历视图前最好选视图模式里删除 calendar 来进行效果查看
表单视图结构
表单视图要么按照简单布局,要么按与纸质文档相似的业务文档布局。我们将学习如何设计这些业务文档布局以及使用可用的元素和组件。要进行这一学习,我们重新查看并扩展第八章 Odoo 12开发之业务逻辑 - 业务流程的支持中创建的图书借阅表单。
业务文档视图
业务应用中记录的很多数据可以按纸质文档那样展示。表单视图可模仿这些纸质文档来提供更直观的用户界面。例如,在我们的应用中,可以把一次借阅看作填写一张纸,我们将编写一个遵循这一设计的表单视图。编辑library_checkout/views/chceckout_view.xml文件并修改表单视图记录来带有业务文档视图的基本框架:
1 | <record id="view_form_checkout" model="ir.ui.view"> |
视图名称是可选的,在不写时会自动生成。为简便以上利用了这一点,在视图记录中省略了
- header状态栏
- sheet主内容
- 底部交流区,也称作chatter
底部的交流区使用了 mail 插件模块中提供的社交网络组件。可使用这些,我们的模型需要继承mail.thread和mail.activity.mixin,可参见第八章 Odoo 12开发之业务逻辑 - 业务流程的支持。
头部 Header
头部header 通常用于文档所走过的生命周期或步骤,还包含相关的操作按钮。这些按钮是普通表单按钮,最重要的下一步可以高亮显示。
头部按钮
编辑表单视图中的
1 | <header> |
这里我们在头部添加了一个Return Books 按钮,在点击时调用button_done模型方法。注意可使用class=”oe_highlight”来对用户高亮显示操作。例如,在有几个可选按钮时,我们可以高亮显示主操作或下一步要执行的“更多”操作。attrs用于在 New 和 Done 状态时隐藏该按钮。实现这点的条件使用了不会在表单显示的 state 字段。要使条件生效,我们需要将使用的所有值在网页客户端中加载。我们不打算向终端用户显示 state 字段,因此使用 invisible 将其添加为不可见字段。
ℹ️domain 或 attrs 表达式中使用的字段必须在视图中加载,作用于它们的
元素。如果字段不对用户可见,则必须以不可见字段元素对其进行加载。
本例中我们使用的是 state 字段,相同的效果可通过 states 字段属性实现。虽然没有 attrs 属性灵活,但它更为精简。可将 attrs 一段替换为如下代码:
1 | <button name="button_done" |
attrs和states元素可见功能也可用于其它视图元素,如 field。本文后续会深入讨论。要让按钮可以运作,我们还需要实现调用的方法。在library_checkout/models/library_checkout.py file文件的借阅类里添加以下方法:
1 | def button_done(self): |
该方法首先查找 done 阶段的记录来使用,然后对 self 记录集中的每条记录,设置其 stage_id 值为完成阶段。
阶段管道
下面我们为头部添加状态条组件,显示文档所在阶段。从代码层面说,是使用statusbar组件的stage_id字段的
1 | <header> |
这会在头部添加一个阶段管道组件,它在表示文档当前所在生命周期点的字段上使用了statusbar组件。通常是一个状态选项字段或阶段many-to-one字段。这两类字段在 Odoo 核心模块中多次出现。clickable属性让用户可通过点击状态条来修改文档阶段。一般需要开启它,但有时又不需要,比如需要对工作进行更强的控制,并且要求用户仅使用可用的操作按钮来进入下一步。这种方法允许在切换阶段时进行指定验证。
对阶段使用状态条组件时,我们可将很少使用的阶段隐藏(折叠)在 More 阶段组中。对应的阶段模型必须要有一个标记来配置需隐藏的阶段,通常命名为 fold。然后statusbar组件使用 options 属性来将这一字段名提供给fold_field选项,如以上代码所示。
使用状态代替阶段
阶段是一个使用了模型来设置进度步骤的many-to-one字段。因此终端用户可对其动态配置来符合他们具体的业务流程以及支持看板的完美展示。我们将在图书借阅中使用到state。
状态是一个包含了流程中相当稳定步骤的选择列表,如新建、处理中和完成。终端用户无法对其进行配置,因为它是静态的,更易于在业务逻辑中使用。视图字段对状态甚至还有特别的支持:状态字段属性仅在记录处理特定状态才对用户开放。
ℹ️阶段引入的时间要晚于状态。两者现在共存,在 Odoo 内核的趋势是使用阶段来替代状态。但如前所述,状态仍提供一些阶段所不具备的功能。
可通过将阶段映射到状态中来同时获得两者的优势。在借阅模型中我们通过向借阅阶段中添加一个状态字段来实现,借阅文档通过一个关联字段来使用状态。使用状态代替阶段的模型中,我们也可以使用进度条管道。这种情况下要在进度条中列出状态,需要使用statusbar_visible属性来替换fold_field选项。具体代码如下:
1 | <field name="state" |
注意在我们实际的图书借阅项目中并不能这么使用,因为它是阶段驱动的,而非状态驱动。
文档表单
表单画布是表单的主区域,这里放置实际的数据元素,设计上类似一张真实的纸质文档,通常 Odoo 中的这些记录也会被称为文档。通常文档表单结构包含如下区域:
- 左上角文档标题和副标题
- 右上角按钮区
- 其它文档头部字段
- 底部笔记区,将附加字段组织成选项卡或页面
文档各行通常在笔记区的第一页,在表单之后,通常有一个 chatter 组件,带有文档订阅者、讨论消息和活动规划。下面逐一了解这些区域。
补充:关于sheet的翻译Alan的理解sheet 仅为单(据),但出于行文习惯一律使用表单
标题和副标题
一个元素之外的字段不会自动带有渲染它们的标签。对于标题元素就是如此,因此该元素应用来对其进行渲染。虽然要花费额外的工作量,但这样的好处是对标签显示控制有更好的灵活性。常规 HTML,包括 CSS 样式元素,可用于美化标题。一般标题放在oe_title类中。以下为扩展后的
1 | <sheet> |
此处可以看到我们使用了div, span, h1和h3这些常规 HTML 元素。
我们还可在表单左上角标题旁包含展示图像。它用在 parnter 或产品这类模型的表单视图中。作为示例,我们在标题区前添加了一个member_image字段,它使用图像组件widget=”image”,以及特定的 CSS 类class=”oe_avatar”。该字段尚未添加至模型中,下面我们就来添加,我们使用关联字段来将会员的图片显示在借阅文档中。编辑library_checkout/models/library_checkout.py文件并在借阅类中添加如下字段:
1 | member_image = fields.Binary(related='member_id.partner_id.image') |
表单内容分组
表单主内容区应通过
继续修改表单视图,在主内容区标题
1 | <group name="group_top"> |
为 group 标签分配name是一个好的编码实践,这样在其它模块中继承时会更易于对它们进行引用。还可设置 string 属性,一旦设置将作为该部分的标题来显示。
ℹ️Odoo 11中的修改
string 属性不能作为继承的锚点,因为在应用继承前会对其进行翻译。这时应使用 name 属性来代替它。
在 group 内,
col 属性可用于
1 | <group name="group_top"> |
以上我们使用 string 属性为组添加了标题,来更清楚地看组所在位置。注意字段的顺序不同,它们先是从左到右,然后从上到下。
选项卡笔记本(Tabbed notebooks)
另一种组织内容的方式是 notebook 元素,一个包含多个称为页面(page)的选项卡分区的容器。它们可以让不常用的内容在不使用时隐藏起来,或者用于按话题组织大量字段。
我们将在借阅表单中添加一个带有已借图书列表的notebook 元素。在前面的
1 | <notebook> |
本例中笔记本仅有一个页面。添加更多,我们需在
- string:选项卡的标题(必填)
- attrs:不可见属性与表达式映射的字典
- accesskey:HTML访问密钥
字段
视图字段有一些可用属性。大部分从模型定义中获取值,但可在视图中覆盖。以下来快速查看字段的可用属性:
- name标识字段数据库中名称
- string用于想要覆盖模型中标签文本的标签文本
- help是鼠标悬停在字段上显示的提示文本,它允许我们覆盖模型定义中提供的帮助文本
- placeholder是在字段中显示的提示文本
- widget让我们可以覆盖字段的默认组件,一会儿我们就会讲到可用的组件
- options是一个带有组件附加数据的JSON数据结构,值随各组件的不同支持而不同
- class是用于字段 HTML 渲染的CSS类
- nolabel=”True”阻止自动字段标签的展示。仅对
元素内的字段有作用,通常与 - invisible=”True”让字段不可见,但仍会从服务端获取数据并可在表单中使用
- readonly=”True”让表单中该字段不可编辑
- required=”True”让表单中该字段为必填
一些特定字段的属性如下:
- password=”True”用于文本字段。显示为密码项,隐藏所输入文字
- filename用于二进制字段,它是用于存储上传文件名的模型字段的名称
字段标签
1 | <label for="name" class="oe_edit_only" /> |
这么做时,如果字段在
字段组件
每个字段类型都会使用相应的默认组件在表单中显示。但还有一些替代组件可以使用。对于文本字段,有如下组件:
- email用于让 email 文本成为可操作的”mail-to”地址
- url用于将文本格式化为可点击的URL
- html用于将文本渲染为HTML内容;在编辑模式下,它显示为一个WYSIWYG(所见即所得)编辑器,可在不使用 HTML 代码的情况下格式化内容。
对于数字字段,有以下组件:
- handle在列表视图中作为一个排序字段,显示一个句柄来让我们可以拖放进行自定义排序
- float_time将一个浮点型字段格式化为带有小时和分钟的值
- monetary将一个浮点型字段显示为货币金额。它与currency_id字段一起使用,还可以通过options=”{‘currency_field’: ‘currency_id’}”来使用另一个字段名
- progressbar将一个浮点值显示为进度条百分比,有助于将字段展示为完成率
- percentage和percentpie组件可用于浮点型字段
对于关联和选择项字段,有以下附加组件:
- many2many_tags将值显示为按钮标签列表
- many2many_checkboxes将选项值显示为一个复选框列表
- selection对many-to-one字段使用选择字段组件
- radio以单选按钮显示选择字段选项
- priority将选项字段显示为一个可点击星形列表。选择项目通常是数值。
- state_selection将看板状态选择列表显示为信号灯。普通状态显示为灰色,完成显示为绿色,其它状态显示为红色。
- pdf_viewer是一个二进制字段(在 Odoo 12中引入)。
ℹ️Odoo 11中的修改
state_selection在 Odoo11中引入来替换掉kanban_state_selection。后者被淘汰,但为保持向后兼容性,还支持使用。
关联字段
在关联字段中,我们可让用户操作做一些额外控制。默认用户从这些字段中创建新记录(也称作“快速创建”)并打开关联记录表单。可通过options字段属性来关闭:
1 | options="{'no_open': True, 'no_create': True}" |
context和domain也是字段属性并对于关联字段特别有用。context可定义关联字记录默认值,domain 可限制可选记录。常见的示例为让一个字段依赖其它字段值来产生选择项。domain可在模型中直接定义,但也可在视图中进行覆盖。
在to-many字段中,我们还可使用 mode 属性来更改用于显示记录的视图类型。默认为 tree,但还有其它选项:form, kanban或graph。关联字段可定义行内指定视图来使用。这些视图在元素中的嵌套视图定义中声明。例如,在line_ids借阅中,我们可以为这些线路定义特定的列表和表单视图:
1 | <notebook> |
线路列表将带有给定的
小贴士: 如果想要在列表视图的表单弹出窗口中直接编辑one-to-many路线,应使用
或
按钮
按钮支持这些属性:
string是按钮文本标签或使用图标时的 HTML alt 文本
type是执行操作的类型,有以下值:
- object用于调用 Python 方法
- action用于运行窗口操作
name标识按所选类型要操作的具体的操作,要么是模型方法名,要么是要运行的窗口操作的数据库 ID。可使用%(xmlid)d方程式来将XML ID转换成加载视图时所需的数据库 ID。
args在类型为 object 时用于向方法传递额外的参数,须是在形成方法调用参数的记录 ID 之后所添加的纯静态 JSON 参数。
context在上下文中添加值,可在窗口操作或 Python 代码方法调用之后产生效果。
confirm在运行相关操作之前显示确认消息框,显示的内容是属性中分配的文本。special=”cancel”用于向导表单。
icon是按钮所显示的图标。可用的按钮来自Font Awesome图标集,版本为4.7.0,应通过对应的 CSS 类来指定,如icon=”fa-question”。更多信息可访问Font Awesome。
ℹ️Odoo 11中的修改
在 Odoo 11之前,按钮图标是来自GTK客户端库的图片,并且仅限于addons/web/static/src/img/icons中所保存图片。ℹ️Odoo 11中的修改
在 Odoo 11中工作流引擎被淘汰并删除。此前的版本中,在支持工作流的地方,按钮可通过type=”workflow”来触发工作流引擎信号。这时name属性用于工作流的信号名。
智能按钮
在右上角版块中带有智能按钮(smart button)也很常见。智能按钮显示为带有数据指示的矩形,在点击时可进入。
Odoo 中使用的 UI样式是在放置智能按钮的地方带有一个隐藏框,按钮框通常是 按钮的容器是一个带有oe_button_box类的 div 元素。在 Odoo 11.0以前,可能需要添加一个oe_right类来确保按钮框在表单中右对齐。在我们的应用中,我们将在按钮中显示图书会员待归还的其它借阅的总数,点击按钮会进入这些项的列表中。 所以我们需要该会员处于 open 状态的借阅记录,排除掉当前借阅。对于按钮统计,我们应创建一个计算字段来在library_checkout/models/library_checkout.py文件的借阅类中进行计数: 下一步我们可以添加按钮框并在其中添加按钮。在 按钮元素本身是一个带有显示数据字段的容器。这些数据是使用statinfo特定组件的普通字段。该字段通常是作用于模型中定义的计算字段。除字段外,在按钮中还可以使用静态文本,如 智能按钮必须带有class=”oe_stat_button” CSS样式,并应使用 icon 属性来带有一个图标。它有一个type=”action”,表示点击按钮时将运行通过 name 属性标识的窗口操作。%(action_other_checkouts_button)d表达式返回要运行的操作的数据库 ID。 在点击按钮时,我们要查看当前会员的其它借阅列表。这可通过action_other_checkouts_button窗口操作来实现。该操作会使用合适的域过滤器打开一个图书借阅列表。操作和相应的域过滤器在表单上下文之外处理,无法访问表单数据。因此按钮必须在上下文中设置当前member_id 来供窗口操作随后使用。使用的窗口操作必须在表单之前定义,因此我们应在 XML 文件根元素 注意我们在域过滤器中如何使用default_member_id上下文键。该键还会点击按钮链接创建新任务时为member_id字段设置默认值。域过滤器也需要当前 ID。这无需在上下文中明确设置,因为网页客户端会在active_id上下文键中自动进行设置。 以下是可在智能按钮中添加的属性,供您参考: 视图元素还支持一些允许视图按字段值动态变更外观或行为的属性。我们可以有onchange 事件来在编辑表单数据时修改其它字段值,或在满足特定条件时让字段为必填或显示。 onchange机制允许我在某一特定字段变更时修改其它表单字段。例如一个商品字段的 onchange可以在商品被修改时设置价格字段为默认值。在老版本中,onchange 事件在视图级别定义,但8.0之后直接在模型层中定义,无需在视图上做任何特定标记。这通过使用@api.onchange(‘field1’, ‘field2’, …) 装饰器创建模型,来对一些字段绑定 onchange 逻辑。onchange 模型方法在第八章 Odoo 12开发之业务逻辑 - 业务流程的支持中详细讨论过,其中还有相关示例。 onchange 机制还可以在用户输入时即时反馈进行计算字段的自动重算。继续使用商品来举例,如果在修改商品时价格字段变化了,它还会根据新的价格自动更新计算后的总金额字段。 一些属性允许我们根据记录的值来动态变更视图元素的显示。指定用户界面元素的可见性可通过如下属性很方便地控制: 除这些以外,我们有一些灵活的方法来根据客户端动态生成的表达式设置元素可见性。它是一个特别属性 attrs,它的值为一个映射invisible属性值与表达式结果的字典。例如,要让closed_date字段在new和open状态时不可见,可使用如下代码: invisible不只在字段中可用,在任意元素中均可用。例如,它可用于 notebook 页面和group元素中。attrs属性也可为其它两个属性设置值:readonly和required。它们仅对数据字段有意义,通过二者来让字段可编辑或为必填。这让我们可以实现一些基础客户端逻辑,如根据其它字段值(如 state)来让字段设为必填。 学到这里可能不太需要介绍列表视图了,但它还一些有趣的额外属性可以讨论。下面我们修改library_checkout/views/checkout_view.xml文件来改进第八章 Odoo 12开发之业务逻辑 - 业务流程的支持中的版本: 行文本颜色和字体可根据 Python 表达式计算结果来动态变化。这通过decoration–NAME属性带上计算字段属性的表达式来实现。NAME可以是bf或it,分别表示粗体和斜体,也可以是其它Bootstrap文本上下文颜色:danger, info, muted, primary, success或warning。Bootstrap文档中有相关显示示例。 ℹ️Odoo 9中的修改 记住表达式中使用的字段必须要在 列表视图可包含字段和按钮,表单中的大部分属性对它们也有效。在列表视图中,数值字段可显示为对应列的汇总值。为字段添加一个累加属性(sum, avg, min或max)会为其分配汇总值的标签文本。我们在 num_books 字段中添加了一个示例: num_books字段计算每个借阅中的图书数量,它是一个计算字段,我们需要在模型进行添加: 可用的搜索选项通过 在 这两个过滤器可以分别被启用并以 OR运算符连接。以 第三个过滤器仅设置 group by 上下文键,它让视图按照字段来对记录分组,本例中为 member_id 字段。 字段元素可使用如下属性: 过滤元素有以下可用属性: 表单、列表和搜索视图是最常用的视图类型。但还有一些其它的视图类型可用于设计用户界面。对于前述三种基本视图类型我们已经很熟悉了,在第十一章 Odoo 12开发之看板视图和用户端 QWeb中将详细介绍看板视图,它会将记录可视化为卡片形式,甚至会按列组织为看板。下面我们将学习一些其它视图类型: 以下两种视图类型用于显示累加数据: 还有更多的视图类型,但仅在 Odoo 企业版中可用。因为我们整个系列的文章是基于社区版的,所以无法为这些视图提供示例: 官方文档中提供了对所有视图和可用属性很好的参考,这里就不再重复。我们集中于提供一些基础使用示例,这样可以对这些视图入门。这样应该可以提供一个很好的基础,然后可进一步探索每个视图的所有功能。 小贴士: 可通过社区插件模块查看其它视图类型。OCA 管理的网页客户端插件请见 GitHub 仓库。例如,web_timeline模块提供了一个时间线视图类型,也可像甘特图那样展示计划信息,它是社区版的 gantt 视图类型。 活动视图类型是内置的计划活动汇总板,帮助用于可视化活动任务。由 mail 模块提供,因此需要先安装该模块才能使用这一视图类型。要使用这一类型,只需在窗口操作的 view_code 属性的视图列表中添加活动视图类型即可。实际的视图定义会自动生成,我们也可以手动进行添加,唯一的选项是修改 string 属性,但在UI 中并不使用。 作为参考,活动视图的定义类似这样: 从名称可以看出,该视图类型在日历中展示记录,可通过不同时间区间浏览:按月、按周或按日。以下是我们图书借阅的日历视图,根据请求日期在日历上显示各项: 补充:请记得在菜单xml文件中加回前文删除的 calendar 类型 基础的日历属性有: ℹ️Odoo 11中的修改 还可通过透视表查看数据,它是一个动态分析矩阵。为此我们可使用透视表视图。 ℹ️Odoo 9中的修改 数据累加仅对数据库中存储的字段可用。我们将使用num_books字段来展示一些借书数量的统计。它是一个计算字段,还没有存储在数据库中。要在这些视图中使用,需要通过添加store=True属性先将其存储在数据库中: 使用如下代码来为图书借阅添加数据透视表: 图表和透视表视图应包含描述轴和度量的字段元素,两者的属性大多数都通用: 图表视图将数据累加展示为图表,可以使用柱状图、线状图和饼图。下面来为图书借阅添加图表视图: 图表视图元素可带有一个type属性,值可为 bar(默认), pie或line。对于 bar,可使用额外的stacked=”True”属性来让柱状图叠放起来。图表使用两种类型字段: 图表和透视表视图应包含描述需使用的轴和度量的字段元素。大多数图表视图中的属性同样可在透视表视图中使用。 本文中我们学习了更多创建用户界面的 Odoo 视图。我们深入讲解了表单视图,然后一起概览了其它视图类型,包括列表视图和搜索视图。我们还学习了如何向视图元素添加动态行为。 下一篇文章中,我们将学习本文中未涉及到的视图:看板视图以及它使用的模板语言 QWeb。 ☞☞☞第十一章 Odoo 12开发之看板视图和用户端 QWeb 以下本文中所讨论的话题的附加参考和补充材料: 本文首发地址:Alan Hou 的个人博客1
2
3<div name="button_box" class="oe_button_box">
<!-- Smart buttons will go here... -->
</div>1
2
3
4
5
6
7
8
9
10num_other_checkouts = fields.Integer(
compute='_compute_num_other_checkouts')
def _compute_num_other_checkouts(self):
for rec in self:
domain = [
('member_id', '=', rec.member_id.id),
('state', 'in', ['open']),
('id', '!=', rec.id)]
rec.num_other_checkouts = self.search_count(domain)1
2
3
4
5
6
7
8
9
10
11
12<div name="button_box" class="oe_button_box">
<button class="oe_stat_button"
icon="fa-tasks"
help="Other checkouts pending return."
type="action"
name="%(action_other_checkouts_button)d"
context="{'default_member_id': member_id}">
<field string="To Return"
name="num_other_checkouts"
widget="statinfo" />
</button>
</div>1
2
3
4
5
6
7<act_window id="action_other_checkouts_button"
name="Open Other Checkouts"
res_model="library.checkout"
view_mode="tree,form"
domain="[('member_id', '=', default_member_id),
('state', 'in', ['open']),
('id', '!=', active_id)]"/>
动态视图元素
onchange 事件
动态属性
1
2<field name="closed_date"
attrs="{'invisible':[('state', 'in', ['new', 'open'])]}"/>列表视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<record id="view_tree_checkout" model="ir.ui.view">
<field name="name">Checkout Tree</field>
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<tree
decoration-muted="state in ['done', 'cancel']"
decoration-bf="state=='open'">
<field name="state" invisible="True" />
<field name="request_date" />
<field name="member_id" />
<field name="checkout_date" />
<field name="stage_id" />
<field name="num_books" sum="# Books" />
</tree>
</field>
</record>
decoration-NAME 属性在 Odoo 9中引入。在 Odoo 8中使用是 colors 和 fonts 属性。
1
<field name="num_books" sum="# Books" /
1
2
3
4
5
6num_books = fields.Integer(compute='_compute_num_books')
@api.depends('line_ids')
def _compute_num_books(self):
for book in self:
book.num_books = len(book.line_ids)搜索视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<record id="view_filter_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<search>
<field name="member_id" />
<field name="user_id" />
<filter name="filter_not_done"
string="To Return"
domain="[('state','=','open')]" />
<filter name="filter_my_checkouts"
string="My Checkouts"
domain="['user_id', '=', uid]" />
<filter name="group_user"
string="By Member"
context="{'group_by': 'member_id'}" />
</search>
</field>
</record>
其它视图类型
活动视图
1
<activity string="Activities"/>
日历视图
1
2
3
4
5
6
7
8
9
10<record id="view_calendar_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<calendar date_start="request_date"
color="user_id">
<field name="member_id" />
<field name="stage_id" />
</calendar>
</field>
</record>
dipsplay 日历属性在 Odoo 11中删除。此前的版本中,它用于自定义日历项标题文本的格式,例如display=”[name], Stage [stage_id]”。透视表视图
透视表在 Odoo 8中就已存在,作为一个图表视图功能。在 Odoo 9中,它成为一个独立的视图类型。同时也增强了透视表功能、优化了透视表数据的获取。1
2
3num_books = fields.Integer(
compute='_compute_num_books',
store=True)1
2
3
4
5
6
7
8
9
10
11<record id="view_pivot_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<pivot>
<field name="stage_id" type="col" />
<field name="member_id" />
<field name="request_date" interval="week" />
<field name="num_books" type="measure" />
</pivot>
</field>
</record>
图表视图
1
2
3
4
5
6
7
8
9<record id="view_graph_checkout" model="ir.ui.view">
<field name="model">library.checkout</field>
<field name="arch" type="xml">
<graph type="bar">
<field name="stage_id" />
<field name="num_books" type="measure" />
</graph>
</field>
</record>
总结
扩展阅读