视图层-设计用户界面
这一章节我们会学习用来构建用户界面的视图层。
- 视图跟控件
- context跟domian
使用xml文件定义用户界面
用户界面与业务记录一样,都是存储在我们Odoo的数据库中。我们设计用户界面其实本质上就是使用xml文件来把Odoo中的UI从数据库中拉出来显示给用户。
构造一个新的 todo_ui 模块.编辑__mainfest__.py
文件:
{
'name': 'User interface improvements tp the To-Do app',
'description': 'User friendly features.',
'author': 'xer',
'depends': ['todo_user'],
'data': ['views/todo_view.xml',
'views/todo_menu.xml',
'security/ir.model.access.csv',
],
}
菜单选项
菜单选项被存贮在ir.ui.menu
模型中.可以在** Settings | Technical | User Interface | Menu Items**中查看
我们在'todo_app'应用中已经创建了顶层菜单'To-Do app tasks'.现在来对这个菜单进行扩展
新建views/todo_menu.xml
.添加如下代码
Odoo的缩写可以直接使用这个标签来代替
- 第一行中我们直接使用了定义在'todo_app'中的菜单视图的外部xml id.直接对其进行改写
- 第二行通过'parent'属性来定义二级菜单,使用action来调用菜单动作.
- 第三行我们定义了一个设置菜单,规定了group为管理员才能获取.
- 最后,我们添加了Stage菜单.绑定action用来显示任务的阶段.
窗口动作(actions)
窗口动作通常与菜单以及按钮结合使用,它在GUI客户端中调度每个窗口。通过domian过滤器能显示记录中符合条件的子集,通过context可以传递参数。
我们在'views/todo_menu.xml'中添加窗口动作,注意要把这些元素放在menu元素之前.窗口动作被存贮在'ir.actions.act_window'模型中,可使用缩写
上面代码第一个action我们打开了Task Stages模型.其中主要属性如下所列:
- name: 在视图层显示的动作的名称.
- res_model : 动作要调用的模型
- view_mode: 视图显示模式。第一个模式是默认打开时的显示方式
- target: new能打开新窗口,默认是current,即在当前页面打开
- context: 在目标视图打开时,提供传递的参数(传递上下文)。通常用来设置默认值以及添加过滤
- domain:domain过滤规则。
- limit: 每页显示的记录数。
第二个action我们重新定义了todo_app中的动作,添加了多种视图表示模式
第三个动作并没有绑定菜单.这个动作是注册到了我们视图层右上角的more选项中. - src_model :指定了在哪个模型中放置More菜单
- multi: 这个属性默认为false,当设置为True时能够在list视图中使用(注意到我们的More菜单只在点开具体task记录时才可以使用)
Context(上下文)跟domain
Context 数据
上下文数据是一个保存着会话信息的字典能够同时在用户界面跟业务后台中传递数据。
- 从用户界面角度:它能把前一个视图中的数据,例如记录ID传递到下一个视图。为下一个视图传递默认值
- 从服务器角度:一些记录集字段的值依赖于Odoo的本地设置,也可以使用context传递。特别是
lang
的值,它是翻译的关键.举个例子:
{'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': 1}
- 当打开一个表单视图或者从按钮上获取一个链接,
active_id
被添加到context
中.它代表了当前记录的id,如果是列表视图,则会有一个active_ids
包含列表中所有的记录. - 如果要设置默认值,要通过
default_
或者default_search_
前缀.举例:
设置默认user_id
字段的值
{'default_user_id' : uid}
设置一个默认的过滤器:
{'default_search_filter_my_tasks' : 1}
Domain表达式
domian表达式是用来过滤数据记录的。它本质是通过Odoo的ORM模型转换为SQL的WHERE子句。domain表达式的每个条件是一个三元素的元组格式:('field_name','operator','value')
- field_name: 是要被过滤的字段名称。能够使用
.
操作符来表示关联模型的字段. - value : 必须能通过操作符跟字段进行比较。
- operator: 操作符。常见的如
<,>,<,>=,=,!=
-
=like
:可以使用模式匹配,下划线“_”匹配一个字符,百分号“%”匹配零或者多个字符。 -
like
:%value%
模式,模糊搜索。ilike
与like
类似,忽略大小写.not like
,通过%value%
模式不匹配 -
child of
:判断是否value的子记录,通过_parent_name实现。 -
in
,not in
:判断value是否在元素的列表里面。
domain表达式是一个列表,通常包含了许多个条件元组,这些条件元组直接默认的逻辑关系是AND。
条件间使用的逻辑前缀:
-
& :逻辑 AND,条件间的默认关系。2个参数(后2个条件或者条件组合) ,例如:
['&', ('partner_id.coutnry_id.code', '=', 'CN'), ('partner_id.coutry_id.code', '=', 'US')]
这里的 & 就是把后面的2个条件通过AND组合起来也就是 A AND B,但是注意到这里说的是还有“条件组合”的情况,所以还有可能是
['&', ('partner_id.coutnry_id.code', '=', 'CN'),
'&',('partner_id.coutry_id.code', '=', 'US'), ('partner_id.coutry_id.code', '=', 'GB')]
转换为一般的表示方法则是 A AND (B AND C),但是因为’&’是默认的逻辑关系,所以我们其实可以不用显式表示
[('partner_id.coutnry_id.code', '=', 'CN'),('partner_id.coutry_id.code', '=', 'US'),
('partner_id.coutry_id.code', '=', 'GB')]
更多的Domain讨论可以在 Domain规则中看到
表单视图
form视图就像纸质文件一样,有着简单的布局。
我们可以对它进行布局的设置,现在让我们通过继承来扩展在todo_app中定义过的form视图.
处理相同类型的多个视图.
同一个模型可能会有多个视图,通过添加action的属性view_id
,可以指定需要使用的视图.
Odoo为我们的模型提供了最为基础的form视图,当我们进行视图的修改后,Odoo会通过优先值来调用新视图.默认的视图优先级为16.
业务文档视图
正常业务使用中,许多记录都被记录在纸质文件上,例如发票,库存单.因此构建一张类似纸质文件的视图是十分有必要的.在我们的To-Do Task中,创建views/todo_views.xml文件.
todo.task
15
业务文档视图通常使用3个主要区域。
- header:状态条
- sheet: 主要内容
- chatter:底部防止留言板一类的界面显示
我们在chatter中使用了Odoo中mail模块的社交网络组件。
header
通常我们在页面头部中放置动作按钮以及页面的生命周期状态。
通常action是通过放置button按钮来实现的。通常使用`class="oe_highlight"可以使其高亮显示
文档记录的生命周期使用'statusbar'这个窗口组件.一般使用'State'名称的selection字段或者一个'Stage'名字的多对一字段来表示文件记录当前的状态.
按照目前Odoo的趋势.逐渐使用Stage代替State来表示记录状态.
在todo_view.xml中扩展我们的header
我们使用字段前,首先需要把该字段导入到view中。
上面的代码中。首先我们把记录的state字段设置为不可见,可以设置属性invisible="True"
让字段在客户界面不显示.
下面定义一个button按钮来触发以前定义过的do_toggle_done
方法.属性"attrs"的定义是指当文档记录的state
状态为draft
时隐藏该按钮.
clickable
属性允许通过点击status bar
来改变文档记录的stage字段值.
Sheet
sheet 标签中主要是实际数据存放的地方,它被设计成跟纸质文档类似的格式。它的主要结构:
- 居中的文档标题
- 右上角的一个按钮盒
- 其他文档头部字段
- 一个用来记载额外字段的笔记本
标题跟副标题
在 右上角有一个按钮存放的区域。我们可以在其中添加按钮. 我们表单的主要内容应该放置在 效果如下: 我们在定义group标签时,可以定义一个 在group标签中我们可以使用 另一种格式化内容的方式是使用 刚才我们解释了如何结构化表单内容。现在我们来讲讲构造表单数据的部件。 视图中字段同样有许多属性,我们可以通过定义这些属性来重写模型中已经定义的字段的属性。 label元素通常用来控制字段在视图中的显示. 表示只有当处于编辑模式时才显示字段标签。 关系字段可用的属性有 可以关闭快速创建功能. 字段根据自己的类型都有默认的窗口显示控件.当我们还可以自己来选择额外的窗口显示控件. 对于字符型字段: 关系型字段: 按钮支持下面的属性: icon : 定义图标按钮。只能在 string : 按钮的字符描述 type : 一共有3个值: name : 根据type的取值来设置.如果是工作流,就是一个工作流信号名称, object就是python方法名,action就是动作的外部id args : 当type参数是object时用来传递参数 context : 添加上下文内容. confirm : 确认按钮上显示的字符 special="cancel" : 在向导中使用.用来取消向导表单或者关闭向导视图. 就是表单结构中右上角的按钮小盒子. 在我们的app中,我们定义了了一个展示当前task总数的按钮,点击它会直接列出当前用户的task列表记录. 首先在 todo_model.py 文件中添加统计task的计算字段, 然后在视图层添加button按钮
元素外的字段不会自动生成标注。所以我, 需要为这些标题元素添加label属性。Odoo的xml文件中可以使用html跟css语言。我们一般把标题放在
By
的用法.for属性指定了需要的字段.
class="oe_edit_only"
表示只在编辑模式时显示该字段.巧妙的按钮区域
标签中.一个字段值跟一个字段标签通常需要两列,而一个
标签会在页面布局上插入两列。所以我们使用2个group标签,这样就可以构造左右两个字段的布局格式。
name
属性,这有利于关联以及以后的扩展.col
,colspan
属性来对布局进一步的控制.
分页笔记本
notebook
元素.包含多重分页节选。它能让不常用的数据在使用时才显示。
例子:视图语义组件
Fields
字段的标签
注意,在group元素内嵌中,我们还要设置nolabel="True"
.关系字段
context,domain
.这些已经介绍过.还有一个options
属性.我们知道,在关系型字段上,我们能够使用快速创建功能来快速创建一个新的关联模型记录,通过options={'no_open': True, 'no_create' : True}
字段窗口控件
对于数字字段:
按钮
addons/web/static/src/img/icons
中获取
1. workflow
: 触发工作流
2. object
: 调用python方法
3. action
: 执行窗口动作巧妙(Smart)按钮
def compute_user_todo_count(self):
for task in self:
task.user_todo_count = task.search_count([('user_id', '=', task.user_id.id)])
user_todo_count = fields.Integer('User To-Do Count', compute='compute_user_todo_count')