行动¶
操作定义系统响应用户操作的行为:登录、操作按钮、选择发票……
Actions can be stored in the database or returned directly as dictionaries in e.g.按钮方法。所有操作都共享两个强制属性:
type当前操作的类别,确定可以使用哪些字段以及如何解释操作
name用户可读的操作简短描述,可以显示在客户端界面中
客户端可以通过 4 种形式获取操作:
False如果当前打开任何操作对话框,请将其关闭
- 一个字符串
如果 client action 匹配,则解释为客户端操作的标记,否则视为数字
- 一个数字
从数据库中读取相应的操作记录,可以是数据库标识符或 external id
- 一本字典
视为客户端操作描述符并执行
绑定¶
除了两个强制属性之外,所有操作还共享用于在任意模型的上下文菜单中呈现操作的“可选”属性:
binding_model_id指定动作绑定到哪个模型
注解
对于服务器操作,请使用“
model_id”。binding_type指定绑定的类型,主要是操作将出现在哪个上下文菜单下
- ``action``(默认)
指定该操作将出现在绑定模型的 上下文菜单中。
report指定该操作将出现在绑定模型的 上下文菜单中。
binding_view_types以逗号分隔的视图类型列表,其操作出现在上下文菜单中,主要是“列表”和/或“表单”。默认为
list,form(列表和表单)
窗口操作 (ir.actions.act_window)¶
最常见的操作类型,用于通过 views 呈现模型的可视化:窗口操作为模型(以及可能的模型的特定记录)定义一组视图类型(以及可能的特定视图)。
其字段有:
res_model模型来呈现视图
views(view_id, view_type)pairs. The second element of each pair is the category of the view (list, form, graph, …) and the first is an optional database id (orFalse的列表)。如果未提供 id,客户端应获取请求模型的指定类型的默认视图(这由fields_view_get()自动完成)。列表的第一种类型是默认视图类型,并且在执行操作时默认打开。每种视图类型在列表中最多应出现一次- ``res_id``(可选)
如果默认视图是“
form”,则指定要加载的记录(否则应创建新记录)- ``search_view_id``(可选)
(id, name)pair,id是要为操作加载的特定搜索视图的数据库标识符。默认获取模型的默认搜索视图- ``target``(可选)
是否应在主要内容区域中打开视图(
current), in full screen mode (fullscreen) or in a dialog/popup (new). Usemaininstead ofcurrentto clear the breadcrumbs. Defaults tocurrent。- ``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(default=list,form)以逗号分隔的视图类型列表作为字符串(/!\ 无空格/!\)。所有这些类型都将出现在生成的
viewslist (with at least aFalseview_id 中)view_idsM2M[#notquitem2m]_查看对象,定义``views``的初始内容
注解
Act_window 视图也可以通过
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`` list in case its type is part of the
view_modelist and not already filled by one of the views in ``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 序列的服务器端组成如下:
获取每个``(id, type)`` from
view_ids(ordered bysequence)如果``view_id`` is defined and its type isn’t already filled, append its
(id, type)对于“
view_mode`, append ``(False, type)`”中的每个未填充类型
- 1
从技术上讲,它不是 M2M:添加了一个序列字段,并且可能仅由视图类型组成,没有视图 id。
URL 操作 (ir.actions.act_url)¶
允许通过 Odoo 操作打开 URL(网站/网页)。可以通过两个字段进行定制:
url激活操作时要打开的地址
target(default=new)可用的值为:
new:在新窗口/页面中打开 URLself:在当前窗口/页面中打开 URL(替换实际内容)download:重定向到下载 URL
例子:
{
"type": "ir.actions.act_url",
"url": "https://www.chinaodoo.com",
"target": "self",
}
这将用 Odoo 主页替换当前内容部分。
服务器操作 (ir.actions.server)¶
允许从任何有效的操作位置触发复杂的服务器代码。只有两个字段与客户相关:
id要运行的服务器操作的数据库内标识符
- ``context``(可选)
运行服务器操作时使用的上下文数据
数据库内记录更加丰富,可以根据其“state”执行许多特定或通用操作。一些字段(和相应的行为)在状态之间共享:
model_idOdoo 模型与动作相关联。
state
code: Executes python code given through thecode参数。object_create: Creates a new record of modelcrud_model_idfollowingfields_lines规格。object_write: Updates the current record(s) followingfields_lines规格multi: Executes several actions given through thechild_ids参数。
状态字段¶
根据其状态,行为是通过不同的字段定义的。相关状态在每个字段后给出。
- ``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>
注解
该代码段可以定义一个名为“
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``(创建)(必需)
创建新记录的模型
- ``link_field_id``(创建)
Many2one 到
ir.model.fields,指定应设置新创建记录的当前记录的 m2o 字段(模型应匹配)- ``fields_lines``(创建/写入)
创建或复制记录时要覆盖的字段。
One2many包含以下字段:col1ir.model.fieldsto set in the concerned model (crud_model_idfor creates,model_id用于更新)value该字段的值,通过“
type”解释- ``type``(值|reference|方程)
如果
value, thevaluefield is interpreted as a literal value (possibly converted), ifequationthevalue字段被解释为 Python 表达式并计算
- ``child_ids``(多)
指定要在状态 multi 中执行的多个子操作 (
ir.actions.server)。如果子操作本身返回操作,则最后一个操作将作为多重操作自己的下一个操作返回给客户端
评估背景¶
在服务器操作或周围服务器操作的评估上下文中可以使用许多键:
报告操作 (ir.actions.report)¶
触发报告的打印。
如果您通过 <record> 而不是 <report> 标签定义报告,并希望该操作显示在模型视图的“打印”菜单中,则还需要指定 binding_model_id from 绑定. It’s not necessary to set binding_type to report, since ir.actions.report 将隐式默认为该值。
- ``name``(强制)
如果未指定“
print_report_name”,则用作文件名。否则,仅在在某种列表中查找报告时用作报告的助记符/描述- ``model``(强制)
您的报告将涉及的模型
- ``report_type``(默认=qweb-pdf)
HTML 的“
qweb-pdf`for PDF reports or ``qweb-html`”- ``report_name``(强制)
用于呈现报告的 qweb 模板的名称 (external id)
print_report_name定义报告名称的 python 表达式。
groups_id允许查看/使用当前报告的组的
Many2many字段multi如果设置为“
True”,该操作将不会显示在表单视图上。paperformat_idMany2one字段填写您希望用于此报告的纸张格式(如果未指定,将使用公司格式)attachment_use如果设置为“
True”,则仅在第一次请求时生成一次报告,然后从存储的报告中重新打印,而不是每次都重新生成。可用于只能生成一次的报告(例如出于法律原因)
attachment定义报告名称的 python 表达式;该记录可通过变量“
object”进行访问
客户端操作 (ir.actions.client)¶
触发完全在客户端执行的操作。
tag操作的客户端标识符,客户端应该知道如何做出反应的任意字符串
- ``params``(可选)
与客户端操作标记一起发送到客户端的附加数据的 Python 字典
- ``target``(可选)
是否应在主要内容区域中打开客户端操作(
current), in full screen mode (fullscreen) or in a dialog/popup (new). Usemaininstead ofcurrentto clear the breadcrumbs. Defaults tocurrent。
{
"type": "ir.actions.client",
"tag": "pos.ui"
}
告诉客户端启动销售点接口,服务器不知道 POS 接口如何工作。
计划的操作 (ir.cron)¶
操作按预定义的频率自动触发。
name计划动作名称(主要用于日志显示)
interval_number两次执行操作之间的 interval_type uom 数
interval_type频率间隔的测量单位 (
minutes,hours,days,weeks,months)model_id将调用此操作的模型
code操作的代码内容。可以是对模型方法的简单调用:
model.<method_name>()
nextcall此操作的下一个计划执行日期(日期/时间格式)
priority同时执行多个动作时动作的优先级
编写 cron 函数¶
运行计划操作时,建议您尝试对进度进行批处理,以避免长时间阻塞工作人员并可能遇到超时异常。因此,您应该拆分处理,以便每个调用都能在一些需要完成的工作上取得进展。
编写此类函数时,您应该专注于处理单个批次。一个批次应该处理一条或多条记录,并且通常应该不超过*几秒钟*。
框架在每批之后提交工作。框架将根据需要多次调用该函数来处理剩余的工作。不要重新安排自己的工作。
def _cron_do_something(self, *, limit=300): # limit: allows for tweaking
domain = [('state', '=', 'ready')]
records = self.search(domain, limit=limit)
records.do_something()
# notify progression
remaining = 0 if len(records) == limit else self.search_count(domain)
self.env['ir.cron']._commit_progress(len(records), remaining=remaining)
在某些情况下,您可能希望在多个批次之间共享资源或自己管理循环以处理异常。在这种情况下,您应该通过调用 IrCron._commit_progress() 并检查结果来通知调度程序您的工作进度。进度函数返回调用剩余的秒数;如果为0,则必须尽快返回。
以下示例说明了如何在处理每条记录后提交,同时保持连接打开。
def _cron_do_something(self):
assert self.env.context.get('cron_id'), "Run only inside cron jobs"
domain = [('state', '=', 'ready')]
records = self.search(domain)
self.env['ir.cron']._commit_progress(remaining=len(records))
with open_some_connection() as conn:
for record in records:
# You may have other needs; we do some common stuff here:
# - lock record (also checks existence)
# - prefetch: break prefetch in this case, we process one record
# - filtered_domain: record may have changed
record = record.try_lock_for_update().filtered_domain(domain)
if not record:
continue
# Processing the batch here...
try
record.do_something(conn)
if not self.env['ir.cron']._commit_progress(1):
break
except Exception:
# if you handle exceptions, the default stategy is to
# rollback first the error
self.env.cr.rollback()
_logger.warning(...)
# you may commit some status using _commit_progress
运行 cron 函数¶
您不应该直接调用 cron 函数。运行函数有两种方法:
cron 函数的测试应通过在注册表测试模式下调用 IrCron.method_direct_trigger() 来完成。
安全¶
为了在计划操作之间保持资源的公平使用,一些安全措施可确保计划操作的正确运行。
如果计划的操作连续三次遇到错误或超时,它将跳过当前执行并被视为失败。
如果计划操作在至少 7 天内连续五次执行失败,则该操作将被停用并通知数据库管理员。
数据库级别的 cron 执行存在硬限制,执行 cron 作业的进程将被终止。