操作¶
动作定义了系统响应用户操作时的行为:登录、动作按钮、选择发票……
动作可以存储在数据库中,也可以直接以字典的形式返回(例如在按钮方法中)。所有动作都有两个必填属性:
type当前动作的类别,决定可以使用哪些字段以及如何解释该动作
name动作的简短描述,便于用户阅读,可能会显示在客户端界面中
客户端可以通过 4 种形式获取动作:
绑定¶
除了两个必填属性之外,所有动作还共享一些 可选 属性,用于在任意模型的上下文菜单中呈现动作:
binding_model_id指定动作绑定到哪个模型
Note
对于服务器动作,请使用
model_id。binding_type指定绑定类型,主要决定动作将出现在哪个上下文菜单中
action默认)指定该动作将出现在所绑定模型的 上下文菜单中。
report指定该动作将出现在所绑定模型的 上下文菜单中。
binding_view_types以逗号分隔的视图类型列表,动作会在这些视图类型的上下文菜单中出现,通常为 “list” 和/或 “form”。默认为
list,form列表和表单)
窗口动作(ir.actions.act_window)¶
最常见的动作类型,用于通过 视图 呈现模型的可视化展示:窗口动作为一个模型(以及该模型可能特定的记录)定义一组视图类型(以及可能的特定视图)。
其字段如下:
res_model要为其呈现视图的模型
views由
(view_id, view_type)对组成的列表。每一对的第二个元素是视图的类别(list、form、graph 等),第一个元素是可选的数据库 id(或False)。如果未提供 id,客户端应为所请求的模型获取指定类型的默认视图(此操作由fields_view_get()自动完成)。列表中的第一个类型是默认视图类型,动作执行时将默认打开该视图。每种视图类型在列表中最多只能出现一次res_id可选)如果默认视图是
form,则指定要加载的记录(否则应创建一条新记录)search_view_id可选)(id, name)对,其中id是为该动作加载的特定搜索视图的数据库标识符。默认情况下会获取该模型的默认搜索视图target可选)视图是应在主内容区域(
current)中打开、以全屏模式(fullscreen)打开,还是在对话框/弹出窗口(new)中打开。使用main代替current可清除面包屑导航。默认为current。context可选)传递给视图的附加上下文数据
domain可选)隐式添加到所有视图搜索查询中的过滤域
limit可选)列表中默认显示的记录数量。在 Web 客户端中默认为 80
例如,要以列表和表单视图打开客户(设置了 customer 标识的业务伙伴):
{
"type": "ir.actions.act_window",
"res_model": "res.partner",
"views": [[False, "list"], [False, "form"]],
"domain": [["customer", "=", true]],
}
或者在新对话框中打开某个特定产品(单独获取)的表单视图:
{
"type": "ir.actions.act_window",
"res_model": "product.product",
"views": [[False, "form"]],
"res_id": a_product_id,
"target": "new",
}
数据库中的窗口动作有几个不同的字段,客户端应忽略这些字段,它们主要用于组合 views 列表:
view_mode默认值 =list,form)以逗号分隔的视图类型列表,采用字符串形式(/!\ No spaces /!\)。所有这些类型都会出现在生成的
views列表中(至少带有一个False的 view_id)view_ids指向视图对象的 M2M1,定义
views的初始内容Note
窗口动作视图也可以通过
ir.actions.act_window.view清晰地定义。如果您计划为模型允许多个视图,请优先使用 ir.actions.act_window.view,而不是动作的
view_ids<record model="ir.actions.act_window.view" id="test_action_tree"> <field name="sequence" eval="1"/> <field name="view_mode">list</field> <field name="view_id" ref="view_test_tree"/> <field name="act_window_id" ref="test_action"/> </record>
view_id在以下情况下添加到
views列表中的特定视图:其类型属于view_mode列表,且尚未被view_ids中的某个视图填充
这些属性主要在通过 数据文件 定义动作时使用:
<record model="ir.actions.act_window" id="test_action">
<field name="name">A Test Action</field>
<field name="res_model">some.model</field>
<field name="view_mode">graph</field>
<field name="view_id" ref="my_specific_view"/>
</record>
将使用 “my_specific_view” 视图,即使它不是该模型的默认视图。
服务器端对 views 序列的组合方式如下:
从
view_ids中获取每个(id, type)按sequence排序)如果定义了
view_id且其类型尚未填充,则追加其(id, type)对于
view_mode中每个尚未填充的类型,追加(False, type)
- 1
严格来说并不是 M2M:它会添加一个序列字段,并且可以只由一个视图类型组成,而不带视图 id。
URL 动作(ir.actions.act_url)¶
允许通过 Odoo 动作打开 URL(网站/网页)。可以通过两个字段进行自定义:
url激活动作时要打开的地址
target默认值 =new)可用值如下:
new:在新窗口/页面中打开 URLself:在当前窗口/页面中打开 URL(替换当前内容)download:重定向到下载 URL
示例:
{
"type": "ir.actions.act_url",
"url": "https://odoo.com",
"target": "self",
}
这会将当前内容区域替换为 Odoo 主页。
服务器动作(ir.actions.server)¶
允许从任何有效的动作位置触发复杂的服务器代码。只有两个字段与客户端相关:
id要运行的服务器动作的数据库内标识符
context可选)运行服务器动作时要使用的上下文数据
数据库中的记录要丰富得多,并且可以根据其 state 执行多种特定或通用动作。某些字段(以及相应的行为)在各状态之间是共享的:
model_id与该动作关联的 Odoo 模型。
state
code:执行通过code参数传入的 Python 代码。object_create:按fields_lines的规范创建模型crud_model_id的新记录。object_write:按fields_lines的规范更新当前记录multi:执行通过child_ids参数传入的多个动作。
状态字段¶
根据状态不同,其行为由不同的字段定义。每个字段后面注明了对应的状态。
code(code)指定调用该动作时要执行的一段 Python 代码
<record model="ir.actions.server" id="print_instance"> <field name="name">Res Partner Server Action</field> <field name="model_id" ref="model_res_partner"/> <field name="state">code</field> <field name="code"> raise Warning(record.name) </field> </record>
Note
代码段可以定义一个名为
action的变量,它将作为下一个要执行的动作返回给客户端:<record model="ir.actions.server" id="print_instance"> <field name="name">Res Partner Server Action</field> <field name="model_id" ref="model_res_partner"/> <field name="state">code</field> <field name="code"> if record.some_condition(): action = { "type": "ir.actions.act_window", "view_mode": "form", "res_model": record._name, "res_id": record.id, } </field> </record>
将在记录满足某些条件时要求客户端为该记录打开表单
crud_model_id(create)(必填)在其中创建新记录的模型
link_field_id(create)指向
ir.model.fields的多对一字段,指定当前记录上应当设置新建记录的多对一字段(模型必须匹配)fields_lines(create/write)创建或复制记录时要覆盖的字段。
One2many,包含以下字段:col1要在相关模型中设置的
ir.model.fields创建时为crud_model_id,更新时为model_id)value字段的值,通过
type进行解释type(value|reference|equation)若为
value,则value字段被解释为字面值(可能经过转换);若为equation,则value字段被解释为 Python 表达式并求值
child_ids(multi)指定在 multi 状态下要执行的多个子动作(
ir.actions.server)。如果子动作本身返回动作,则最后一个动作将作为 multi 自身的下一个动作返回给客户端
求值上下文¶
在服务器动作的求值上下文及其周边可以使用许多键:
model通过model_id关联到该动作的模型对象record/records触发该动作的记录/记录集,可以为空。envOdoo 环境datetime、dateutil、time、timezone对应的 Python 模块log: log(message, level='info')用于在 ir.logging 表中记录调试信息的日志函数WarningWarning异常的构造器
报表动作(ir.actions.report)¶
触发报表的打印。
如果您是通过 <record> 标签而非 <report> 标签定义报表,并且希望该动作出现在模型视图的打印菜单中,还需要指定 绑定 中的 binding_model_id。无需将 binding_type 设置为 report,因为 ir.actions.report 会隐式默认为该值。
name(必填)在未指定
print_report_name时用作文件名。否则,仅在某种列表中查找报表时用作助记名/描述model(必填)报表所针对的模型
report_type(默认为 qweb-pdf)PDF 报表用
qweb-pdf,HTML 则用qweb-htmlreport_name(必填)用于渲染报表的 qweb 模板的名称(external id)
print_report_name定义报表名称的 Python 表达式。
groups_idMany2many字段,指向允许查看/使用当前报表的群组multi如果设为
True,该动作将不会显示在表单视图上。paperformat_idMany2one字段,指向希望用于该报表的纸张格式(如未指定,将使用公司格式)attachment_use如果设为
True,报表只在首次请求时生成一次,之后从存储的报表重新打印,而不会每次都重新生成。可用于只需生成一次的报表(例如出于法律原因)
attachment定义报表名称的 Python 表达式;记录可以通过变量
object访问
客户端动作(ir.actions.client)¶
触发一个完全在客户端实现的动作。
tag动作的客户端标识符,一个任意字符串,客户端应知道如何对其作出响应
params(可选)随客户端动作标签一起发送给客户端的附加数据,为一个 Python 字典
target可选)指定客户端动作应在主内容区(
current)、全屏模式(fullscreen)还是对话框/弹出窗口(new)中打开。使用main代替current可清除面包屑。默认为current。
{
"type": "ir.actions.client",
"tag": "pos.ui"
}
告诉客户端启动销售点(POS)界面,服务器完全不知道 POS 界面如何工作。
更多内容
计划操作(ir.cron)¶
按预定频率自动触发的操作。
name计划操作的名称(主要用于日志显示)
interval_number动作两次执行之间 interval_type 度量单位的数量
interval_type频率间隔的度量单位(
minutes、hours、days、weeks、months)model_id将在其上调用该操作的模型
code操作的代码内容。可以是对模型方法的简单调用:
model.<method_name>()
nextcall该操作的下一次计划执行日期(日期/时间格式)
priority同时执行多个操作时该操作的优先级
高级用法:批处理¶
执行计划操作时,建议尝试对进度分批处理,以避免长时间占用工作进程,并可能引发超时异常。
Odoo 为计划操作批处理提供了一个简单的 API;
self.env['ir.cron']._notify_progress(done=XX:int, remaining=XX:int)
该方法让调度器知道是否取得了进展,以及是否还有必须完成的剩余工作。
默认情况下,如果使用了该 API,调度器会尝试一次性处理 10 个批次。如果在这 10 个批次之后仍有剩余任务,将尽快执行新的 cron 调用。
高级用法:触发器¶
对于更复杂的用例,Odoo 提供了一种更高级的方式,可以直接从业务代码触发计划操作。
action_record._trigger(at=XX:date)
安全¶
为了在计划操作之间公平地使用资源,一些安全措施确保您的计划操作正常运行。
如果计划操作连续三次遇到错误或超时,它将跳过当前执行并被视为失败。
如果计划操作在至少七天内连续五次执行失败,它将被停用并通知数据库管理员。