你们好鸭,我又来更新啦!还记得咱们在第二篇教程中提到过的动做(actions)吗,今天咱们就来专门讲讲在 Odoo 中的 action
,学习不一样类型的动做对应的应用场景,而且在咱们的 Todo 应用中使用上其中一些类型的动做。git
窗口动做在 Odoo 中是最多见也是最经常使用的动做类型,在第二篇教程中咱们建立菜单的时候就已经用过窗口动做了,咱们打开 menus.xml
来看看一个窗口动做的组成:github
<!-- menus.xml --> <record id="action_todo_task" model="ir.actions.act_window"> <field name="name">待办事项</field> <field name="res_model">todo.task</field> <field name="view_type">form</field> <field name="view_mode">tree,form</field> <field name="target">current</field> </record>
这里的 model
以前咱们也说过,对应的是这个动做的类型(每一个类型的动做都对应一个模型),咱们重点来看看下面列出的字段以及没有列出来的字段,分别说明一下它们各自的做用。web
res_model
:要打开的视图(窗口)关联的数据模型view_type
:视图类型,默认值为 form
,通常状况下咱们取默认值就能够了view_mode
:容许打开的视图类型,以逗号分隔,默认值为 tree,form
target
:打开的窗口类型,经常使用的有 current
(当前窗口打开)和 new
(弹窗打开)这两种,默认为 current
除了上述列出的一些字段外,还有一些非必填的字段在某些时候咱们是会用上的,这里也分列出来:浏览器
view_ids
:关联的视图对象 id,需注意区分和 view_id
的区别view_id
:关联的视图的 id, 例如在不一样时候须要打开同一个数据模型不一样的表单视图,就能够经过这个字段指定要打开的视图的 idres_id
:仅在视图类型为 form
时有效,表示打开该 id 对应的记录的表单视图,如未指定则打开新建页面context
:传递到上下文中的数据,一个字典domain
:过滤规则,对视图中的记录进行过滤limit
:列表中每页显示的记录数量,默认为 80search_view_id
:指定搜索视图,不指定则按默认规则加载multi
:若是设置为 True
且动做绑定了模型(src_model
)的话,该动做按钮会只出如今所绑定模型列表视图的「动做」下拉列表中(在搜索视图左侧)views
:由 (view_id, view_type)
这样的元组对组成的列表,view_id
为指定视图的 id 或是 False
(按默认值取出对应视图),view_type
表示视图类型其中 views
是一个计算字段,该字段会根据 view_ids
, view_mode
和 view_id
自动计算出来,大体分为三个步骤:服务器
view_ids
中顺序取出 id 和视图类型,组成 (view_id, view_type)
元组对加入到 views
列表中view_id
且对应的视图类型不在 view_ids
中,则加入到 views
中view_mode
中指定的视图类型,可是不存在于 view_ids
和 view_id
中,则将其 view_id
置为 False
组成元组对后加入到 views
中这里须要强调一点的是,若是咱们在某些时候须要直接经过 Python 代码或 JS 代码打开一个窗口动做,此时咱们将须要本身添加 views
字段,不然将会抛出错误,具体的实例咱们将在以后使用到了再进行讲解分析。框架
Server Action 能够在服务端执行复杂的逻辑代码,是很是强大的一种动做类型。咱们先给代办事项添加一个 Server Action 用于快速完成任务的动做,这样咱们就不用每次都要点进去一个任务而后进入编辑状态再勾选保存这么多步骤了。dom
咱们来看看定义一个最简单的 Server Action 应该包含哪些内容:学习
<!-- views.xml --> <record id="action_mark_todo_task_done" model="ir.actions.server"> <field name="name">标记完成</field> <field name="model_id" ref="model_todo_task"/> <field name="binding_model_id" ref="model_todo_task"/> <field name="state">code</field> <field name="code">records.write({'is_done': True})</field> </record>
和其余全部在数据文件(XML)中定义的数据同样,首先是一个包含属性 id
和 model
的 <record />
标签,咱们要定义的是 Server Action, 因此须要将 model
设置为 ir.actions.server
,而后是对应 Server Action 模型下的一些字段:google
model_id
:当前的动做是在哪一个模型上运行的binding_model_id
:绑定的模型,当前动做将会出如今绑定的模型的视图中state
:服务器动做的类型,总共有 4 种可选的类型,分别是 code
(执行 Python 代码),object_create
(建立一条新记录),object_write
(更新记录),multi
(执行多个动做)code
:对应 state
的类型 code
,为当前动做运行时所要执行的 Python 代码你们应该都留意到了在上面的定义中出现了一个属性 ref
,若是我没有理解错,它应该是 reference
的缩写,它的值是一个外部 ID(external id
),咱们上面定义的这个动做的外部 ID 就是定义时添加的 id
属性的值 action_mark_todo_task_done
,它指向一条具体的记录(就像 Many2one
字段同样)。url
咱们定义的全部模型都会在 ir.model.data
对应的表中存在相应的记录,这些模型的外部 ID 形如 model_model_name
,其中 model_name
是将模型名 [model.name](http://model.name)
的 .
替换成 _
,例如咱们的 todo.task
模型的外部 ID 就是前缀 model_
加上 todo_task
组成的 model_todo_task
了。
接下来咱们再看到字段 code
里面的内容,在这里面咱们有一些变量是能够直接使用的:
env
:Odoo 的运行环境model
:动做触发时对应的 Odoo 模型实例record
:动做触发时对应的单个记录(如在表单视图中运行对应当前表单所指向的记录),多是空的records
:动做触发时对应的记录集(如在列表视图中勾选多条记录触发,记录集指向这些选中的记录),多是空的time
, datetime
, dateutil
, timezone
时间相关的 Python 库log
:用来记录日志信息Warning
:经过 raise Warning('xxxxx')
抛出警告信息除了上述能够直接使用的变量外,还有一个 action
变量,当咱们想让当前动做执行完毕以后,返回一个新的动做继续执行,就能够将返回的动做的定义(一个字典)赋值给变量 action
,客户端将会自动执行该动做。
OK, 前面说了这么多,咱们更新一下代码,而后刷新浏览器看看效果吧:
在列表视图中,当咱们勾选了任意的记录后,将会出现一个「动做」菜单,打开以后就能够看到咱们刚刚定义的「标记完成」这个 Server Action 了,试试看执行会发生什么,注意观察「已完成?」这一列的变化。而后再建立一条新的记录,在表单页面中,一样有「动做」菜单,咱们在这里也能够执行「标记完成」的动做,怎么样,是否是比本来的编辑再勾选再保存要方便得多了,并且咱们还能在列表里勾选多条记录进行批量操做,不能更方便了!
受限于篇幅,咱们这里只涉及了 state
为 code
类型的服务器动做,相对其余三种类型,已经足以应付绝大多数场景的需求了,这里就不展开细说,感兴趣的同窗能够看看官方模块的相关实现,要学会看源码哈!
URL Action 用来打开一个网页连接,十分简单的一种动做类型:
<record id="action_open_google" model="ir.actions.act_url"> <field name="name">打开谷歌</field> <field name="target">new</field> <field name="url">https://google.com</field> </record>
上面这个动做触发后将会新开浏览器窗口(或新标签)打开谷歌首页,主要的两个字段以下:
target
:有两个可选值,分别是新窗口(new
)打开连接,至关于 <a target='_blank' />
,以及当前窗口(self
)打开,至关于 <a target='_self' />
url
:要打开的目标页面的连接,能够是外部页面也能够是同域下的内部页面触发一个彻底由客户端(浏览器)执行的动做,例如某些模块的「仪表板」就属于 Client Action,它的基本组成以下:
<record id="backend_dashboard" model="ir.actions.client"> <field name="name">Dashboard</field> <field name="tag">backend_dashboard</field> </record>
上面这个 Client Action 是在 Odoo 自带模块 website
中定义,用来打开仪表板,来看看客户端动做有哪些字段是可用的:
tag
:客户端动做的标识,须要是在 action_registry
中注册了的动做target
:同学口动做context
:同学口动做params
:传递给客户端动做的参数,一个字典客户端动做的本体其实是 tag
所指向的动做,这个动做是用 JS 编写的一些逻辑(在 Odoo 的 JS 框架下),在以后会有专门的教程教你们相关的内容,这里请先略过。
这类型的动做用于触发报表打印,例如打印发票等。这里不对该类型做介绍,感兴趣的同窗一样能够去看看 Odoo 自带的一些模块如 account
等。
在实际开发中,最常接触和使用的动做基本上就窗口动做(ir.actions.act_window
)和服务器动做(ir.actions.server
)这两种了,其中 Server Action 最复杂也最强大,能够用它来实现不少的功能。
上面没有展开细说的内容,但愿你们能够多多翻看官方模块的实现,学会阅读源码才是最好的学习方式。
教程中的代码会更新在 GitHub 仓库「Odoo-Tutorial-Demo」中,若是遇到什么问题,欢迎提出,我会及时解答 ;-)