第四章 基本的视图
前面一章介绍了Odoo中的常见的几种字段, 我们学会了如何创建一个模型,并定义他们的字段, 本章我们将介绍如何定义模型的视图, 以及介绍几种常见的视图及其用法.
视图的组成
Odoo的布局是通过视图文件(xml)来组织的,并不需要我们自己写HTML代码,只要我们按照它要求的格式写完xml,前端页面就自动地的生成了。因为视图是前端展示用的,所以视图的种类多种多样,odoo也可以支持自定义视图,这就给了开发人员很大的灵活拓展性。
常见的视图有如下几种:
- 表单视图(Form)
- tree视图
- kanban视图
- graph视图
- gatt视图 ...
每种视图的结构不一样,下面我们将简单介绍一下常见的几种视图的使用方法.
表单视图
我们先来看一下上一节中,我们写的表单视图代码:
<record id="book_store.book_form" model="ir.ui.view">
<field name="name">图书</field>
<field name="model">book_store.book</field>
<field name="arch" type="xml">
<form string="图书详情">
<header>
<button name="button_create" type="object" string="随机添加一个作者" class="oe_highlight"/>
<button name="button_update" type="object" string="给作者们加颗❤️" class="oe_highlight"/>
<button name="button_delete" type="object" string="删除一个作者" class="oe_highlight"/>
<button name="button_clear" type="object" string="删除所有作者" class="oe_highlight"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<label for="name" string="名称" class="oe_edit_only"/>
<field name="name"/>
</h1>
</div>
<group>
<field name="authors" widget="many2many_tags"/>
<field name="date"/>
<field name="price"/>
</group>
</sheet>
</form>
</field>
</record>
首选, 在odoo中,所有的预定义的数据结构都放在record节点中,id是这些数据的唯一标识,叫做xml_id,xml_id在模块内部要保持唯一, 当模块安装以后, xml_id在系统中的唯一标识是模块名.xml_id。xml_id在开发过程中是一个很重要的概念, 这个等后面使用的时候会详细讲到。
model指明本记录所属的对象模型名称,odoo中的视图模型是ir.ui.view,因此这里的值也就是ir.ui.view。
record的子节点,由若干个field节点组成。
- name: 代表的是模型的字段,值根据字段类型的不同,设置方式也不同。本例中,我们给视图命名"图书"。
- model: 视图所属的模型名称,这里我们用到的是自己定义的图书模型,因此写的是book_store.book。
- arch: 视图的布局结构,属性type为固定值xml
每种视图的arch结构都不一样, 对于表单视图来说:
- header: 表头,通常放置按钮和状态栏
- footer:底部,可以放置按钮,也可以放置一些需要的小部件。
- sheet:页面主体。
以原生的销售单部分来说,1 部分即是header 2 是sheet 3是footer。
header
Header的作用通常用来放置一些按钮、动作和状态栏。如上图所示的1部分。
Header的位置通常位于form节点下的第一个。
<form>
<header>
...
</header>
</form>
Sheet
sheet节点虽然不是form表单的必须组成部分,但却是最常用的部分,我们见到的大多数页面都是用到了sheet节点。
Chatter
我们常见的Form表单都有一个类似留言板的讨论区。 这个讨论区的使用方法:
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="activity_ids"/>
<field name="message_ids"/>
</div>
想要使用这个功能的模型必须要继承mail.thread对象。
分组
在表单视图中使用group标签,可以将多个field分组排列并自动生成字段相对应的标签label。
<group>
<field name="serial"/>
<field name="authors" color="red" widget="many2many_tags"/>
<field name="date"/>
<field name="price"/>
<field name="img"/>
</group>
字段
表单视图中使用最多的语法是字段的布局:
<field name="field1" string="description" class="..." attrs="{...}"/>
字段布局的string属性不是必须的, 如果没有明确声明, 那么系统将默认使用字段的name属性作为它的string属性的值.
如果字段的布局中使用了nolabel属性并设置为True, 那么该字段在显示的时候将缺省描述标签label.
odoo17.0 取消了attrs的属性 使用属性直接代替了。
tree视图
把表单视图代码中的form替换成tree就成了我们的列表视图,这里称之为列表视图是因为tree视图并不是真正的"树视图",真正的树视图是可以展开的。
<record model="ir.ui.view" id="book_store.list">
<field name="name">图书列表</field>
<field name="model">book_store.book</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="author"/>
<field name="date"/>
<field name="price"/>
</tree>
</field>
</record>
tree视图相对比较简单,一般就是对本对象要显示的属性的罗列。
列表视图的可编辑属性
默认情况下,列表视图是不可以被编辑的,只能单击进入表单视图进行编辑。这种行为可以通过tree的editable属性进行改变。
<record model="ir.ui.view" id="book_store.list">
<field name="name">图书列表</field>
<field name="model">book_store.book</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="name"/>
<field name="author"/>
<field name="date"/>
<field name="price"/>
</tree>
</field>
</record>
editable的可选值有两个:top和bottom。top是默认值,即不可编辑模式。bottom即可以编辑模式。
使用bottom的效果如下图:
Tree视图的字段的可见性
如果我们想要Tree视图中的某一列不可见,那么我们可以使用invisible属性将其设置为不可见.
<field name="name" invisible="1">
17.0+ 列表视图已不能再使用invisible属性,而应该使用column_invisble。
隐藏或显示属性
13.0+版本后列表视图支持字段的隐藏或显示。设置方法:
<field name="name" optional="hide">
<field name="name" optional="show">
xpath中的position操作attributes对optional属性无效。
设置颜色
我们可以根据不同的情况对Tree的行或者某一列进行颜色设置。
例如,我们想要给列表视图中name字段设置红色,那么我们的代码可以这样写:
<tree>
<field name="name" decoration-danger="red:1">
</tree>
而如果我们希望整个一行都变成红色,那么可以使用下面的方法:
<tree decoration-danger="red:1">
<field name="name">
...
</tree>
odoo中支持的颜色列表,请参考附录
Seach视图
search视图的基本写法:
<search>
...
</serach>
字段过滤
如果想要在搜索菜单中添加搜索字段,那么只需要在field列表中添加即可。
<field name="name">
字段筛选器
如果我们希望把常用的搜索固定在搜索面板中,那么我们可以使用filter属性:
<filter name="name" domain="[('type','=','sale')]"/>
字段分组
如果想要对字段进行分组,同样适用filter属性,不同的是需要使用context来对字段进行分组。
<filter name="name" string="Name" context="{'group_by':'name'}">
多条件搜索
如果我们希望在多个字段中对某个输入值进行匹配,那么我们可以使用filter_domain属性这种方式:
<fitler name="Order" string="Order" filter_domain="[('name','ilike',self),('serie_name','ilike',self)]">
明细行搜索
对于X2Many类型的字段来说也可以进行搜索,方式同filter_domain。可以参考销售订单的明细搜索:
<field name="order_line" string="Product" filter_domain="[('order_line.product_id', 'ilike', self)]"/>
kanban视图
看板视图是一种可以在面板上显示诸多信息的一种视图结构,是odoo最常见的几种视图结构之一。
看板视图的要求在kanban节点内将用到的字段列出来, 看板的布局使用QWEB技术在templates标签内完成。
我们来给图书(book_store.book)添加看板视图:
<record id="book_kanban" model="ir.ui.view">
<field name="name">图书看板视图</field>
<field name="model">book_store.book</field>
<field name="arch" type="xml">
<kanban>
<field name="name"/>
<field name="authors"/>
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
<div class="o_kanban_record_top mb16">
<strong class="o_kanban_record_title">
<span>
<t t-esc="record.name.value"/>
</span>
</strong>
</div>
<div class="o_kanban_record_bottom">
<div class="oe_kanban_bottom_left text-muted">
<field name="authors" widget="many2many_tags"/>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
其效果如下:
总结
视图是odoo开发中的重要部分,是与用户直接交互的UI层, 视图的编写其实是一个挺庞大的内容体系, 涉及到前端QWEB技术和后端的ir.ui.view模型, 关于视图更多的内容,我们将在第二部分中深入介绍, 鉴于读者的学习进程,本章的内容就简要地介绍的到这里。下一章, 我们将介绍Odoo的API 。