视图定义了记录应如何显示给最终用户。它们在 XML 中指定,这意味着它们可以独立于它们所代表的模型进行编辑。它们很灵活,允许对其控制的屏幕进行高级别的定制。存在各种类型的视图。它们中的每一个都代表一种可视化模式:form、list、kanban等。
先看一个实例,去掉FORM菜单的“行动”快捷菜单
修改FORM视图,添加下图中的1和2:
这样处理后,动作下拉菜单就不见了。
通用结构
基本视图通常共享下面定义的通用结构。占位符全部大写。
<record id="MODEL_view_TYPE" model="ir.ui.view">
<field name="name">NAME</field>
<field name="model">MODEL</field>
<field name="arch" type="xml">
<VIEW_TYPE>
<VIEW_SPECIFICATIONS/>
</VIEW_TYPE>
</field>
</record>
字段
视图对象公开了许多字段。除非另有说明,否则它们是可选的。
name(强制的):Char
仅在在某种列表中查找视图时用作视图的助记符/描述。
model: Char
链接到视图的模型。
优先级: Integer
当请求视图时,将返回与模型和类型匹配的视图。
它还定义了视图继承期间视图应用程序的顺序。
groups_id
允许使用/访问当前视图的组。
如果视图扩展了现有视图,则扩展仅适用于给定用户,前提是用户有权访问提供的groups_id.
arch Text
视图布局的描述。
属性
不同的视图类型具有允许自定义通用行为的多种属性.
- create
在视图上禁用/启用记录创建。
- edit( form& list& gantt)
禁用/启用视图上的记录编辑。
- delete( form& list)
通过“操作”下拉菜单在视图上禁用/启用记录删除。
- duplicate( form)
通过“操作”下拉菜单禁用/启用视图上的记录复制。
- decoration-{$name}( list& gantt)
根据相应记录的属性,以行文本的样式定义记录的条件显示。
它的值是 Python 表达式。对于每条记录,使用记录的属性作为上下文值来评估表达式,如果是true,则将相应的样式应用于该行。以下是上下文中可用的其他一些值:
- uid:当前用户的id,
- today: 当前本地日期,形式为字符串YYYY-MM-DD,
- now:today与添加当前时间相同。此值的格式为。YYYY-MM-DD hh:mm:ss
<tree decoration-info="state == 'draft'"
decoration-danger="state == 'help_needed'"
decoration-bf="state='busy'">
<TREE_VIEW_CONTENT>
</tree>
注意:
对于decoration,不同视图支持不同类型. Gantt视图仅支持 success, info, warning, danger 和 secondary 显示. list 视图支持 bf, it, success, info, warning, danger, muted 和 primary 显示.
- sample (kanban & list & gantt & graph & pivot & cohort & dashboard)
如果未找到当前模型的记录,则使用一组sample记录填充视图。默认情况下,此属性为false
这些。
这些虚拟的记录会对一些字段进行自动填充,如:新增一个用户(含电子邮件)
res.users表中的记录:
相关联的res_partner表中的记录:
注:用户将无法与这些数据交互,一旦执行操作(创建记录、添加列等),这些数据将被删除。
- banner_route :要提取并添加到视图的路由地址
如果这个属性被设置,路由地址(URL)对应的内容被会获取并展示在视图上。来自控制器的json响应应该包含一个“html”节点。
如果html节点内容包括标记,它将被移动中。
要与后端交互,可以使用标记。
只有扩展AbstractView和AbstractController的视图才能使用此属性。
示例代码如下:
<tree banner_route="/module_name/hello" />
class MyController(odoo.http.Controller):
@http.route('/module_name/hello', auth='user', type='json')
def hello(self):
return {
'html': """
<div>
<link href="/module_name/static/src/css/banner.css"
rel="stylesheet">
<h1>hello, world</h1>
</div> """
}
继承
继承字段
以下两个视图字段用于指定继承视图.
inherit_id :Many2one
当前视图的父视图,通过ref属性指定。
<field name="inherit_id" ref="library.view_book_form"/>
mode选择: extension / primary
继承模式,请参阅继承。 如果未设置inherit_id,则mode只能是primary。 如果设置了inherit_id,则默认为extension,但可以显式设置为primary
<record id="base_onboarding_company_form" model="ir.ui.view">
<field name="name">base.company.onboarding.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form" />
<field name="mode">primary</field>
<field name="priority">1000</field>
<field name="arch" type="xml">
<xpath expr="//group[@name='social_media']" position="replace" />
<form position="inside">
<footer position="replace">
<button name="action_save_onboarding_company_step" class="btn btn-primary" type="object" string="Apply" data-hotkey="q"/>
<button special="cancel" data-hotkey="z" string="Cancel" />
</footer>
</form>
</field>
</record>
View 调用
如果调用试图采用 (model, type)的方式,则程序会匹配正确的模型和类型,即 mode = primary和最低优先级的视图
如果采用ID的方式调用,如果mode不是primary,则匹配与primary最接近的父模式。
如:
self.a4 = self.View.create({
'model': 'a',
'inherit_id': self.a1.id,
'mode': 'primary',
'arch': '<xpath expr="//a1" position="after"><a4/></xpath>',
})
vals = {
'inherit_id': self.id,
'name': '%s (%s)' % (self.name, el.get('id')),
'arch': self._pretty_arch(arch),
'key': '%s_%s' % (self.key, el.get('id')),
'type': 'qweb',
'mode': 'extension',
}
View的arch节点内容
如果视图有父视图,则完全继承父视图的arch节点内容.
如果没有父视图,必须自行创建arch节点内容.
如果当前视图的子视图,程序会按继承关系一层层修改视图的arch节点内容.
继承规范
继承规范由元素定位器和子元素组成,元素定位器用于匹配父视图中的继承元素,子元素将用于修改继承元素。
分三种情况:
#第一种方式:xpath定位
<xpath expr="page[@name='pg']/group[@name='gp']/field" position="inside">
<field name="description"/>
</xpath>
#第二种方式:field定位
<field name="res_id" position="after"/>
#第三种方式:div定位
<div name="name" position="replace">
<div name="name2">
<field name="name2"/>
</div>
</div>
继承规则选项说明:
inside (默认):附加
replace:替换
after:在后面增加
before:在前面增加
attributes:属性
<field name="sale_information" position="attributes">
<attribute name="invisible">0</attribute>
<attribute name="attrs">
{'invisible': [('sale_ok', '=', False)], 'readonly': [('editable', '=', False)]}
</attribute>
</field>
move:移除元素
<xpath expr="//@target" position="after">
<xpath expr="//@node" position="move"/>
</xpath>
<field name="target_field" position="after">
<field name="my_field" position="move"/>
</field>