总结
1 模型和视图的 设计之美
view_ids, view_id,view_mode 最终目的都是为了生成views, 也就是视图.
模型是死的,像男人,一成不变
视图像女人,千变万化, 姿态万千
一阴一阳之谓道,设计之美又在这里得到了体现
2 所有的动作都可以通过web界面来配置
可以通过在"设置-技术-动作" 定义. 定义好之后会出现在对应模型的动作列表中
动作
动作定义了系统响应用户操作的行为比如,登录、操作按钮、选择发票、…
动作可以存储在数据库中,也可以直接作为字典返回,例如按钮方法。所有动作都有两个强制属性:
type
当前操作的类别决定了可以使用哪些字段以及如何解释操作
name
简短的用户可读的操作描述,可以显示在客户端界面中
客户端可以通过4种形式获得动作:
- False 如果当前打开了任何操作对话框,关闭它
- 字符换: 如果客户端action匹配,将其解释为客户端action的标记,否则将其视为数字
- 数字: 从数据库中读取相应的动作记录,可以是数据库标识符或外部id
- 字典: 将其视为客户端操作描述符并执行
1 绑定 Bindings
除了它们的两个强制属性,所有动作还共享可选属性,用于在任意模型的上下文菜单中显示动作:
1.1 binding_model_id
指定操作绑定到哪个模型
注意: 对于 Server Actions,使用model_id
1.2 binding_type
指定绑定的类型,主要是操作将出现在哪个上下文菜单下
action(default)
指定该动作将出现在绑定模型的action上下文菜单中。
report
指定该操作将出现在绑定模型的“打印”上下文菜单中。
这两个都是在form视图中才有的.
1.3 binding_view_types
一个逗号分隔的视图类型列表,操作将出现在上下文菜单中,主要是“list”和/或“form”。默认为列表,表单(列表和表单)
2 窗口动作(ir.actions.act_window)
最常见的动作类型,用于通过视图呈现模型的可视化:
- 特定的视图类型,如tree.form
- 特定的记录(通过domain来过滤)
有如下字段:
2.1 res_model
视图对应的模型名称
2.2 views(*)
(view_id, view_type)对的列表。每对中的第二个元素是视图(tree、from、graph等)的类别,第一个元素是可选的数据库id(或False)。如果没有提供id,客户端应该为所请求的模型获取指定类型的默认视图(这是由fields_view_get()自动完成的)。列表的第一种类型是默认视图类型,在执行动作时默认打开。每种视图类型在列表中最多只能出现一次
2.3 res_id(可选的)
如果默认视图是form,则指定要加载的记录(否则应该创建一个新记录)
2.4 search_view_id
(optional)
(id, name)对,id是要为操作加载的特定搜索视图的数据库标识符。默认为获取模型的默认搜索视图
2.5 target
(optional)
视图是否应该在主内容区(current)、全屏模式(fullscreen)或对话框/弹出(new)中打开。使用main代替current来清除面包屑。默认为current。
经过测试: 对于URL ACTIONS来说,只有new可以用,其他都报错
2.6context
(optional)
传递给视图的其他上下文数据
2.7 domain
(optional)
过滤域以隐式添加到所有视图搜索查询
2.8 limit
(optional)
默认情况下在列表中显示的记录数。在web客户端中默认为80
2.9 案例
打开合作伙伴中的消费者的视图:
{"type": "ir.actions.act_window","res_model": "res.partner","views": [[False, "tree"], [False, "form"]],"domain": [["customer", "=", true]],
}
或者在新的对话框中打开特定产品的表单视图(单独获得):
{"type": "ir.actions.act_window","res_model": "product.product","views": [[False, "form"]],"res_id": a_product_id,"target": "new",
}
数据库存储的窗口动作有几个不同的字段,应该被客户端忽略,主要用于组成视图列表:
view_mode
(default= tree,form
)
以逗号分隔的视图类型列表(/!)\没有空格/!)。所有这些类型都将出现在生成的视图列表中(至少有一个False view_id)。
view_ids
M2M用于视图对象,定义了视图的初始内容
<record id="hr_leave_allocation_overtime_action" model="ir.actions.act_window"><field name="name">New Allocation Request</field><field name="res_model">hr.leave.allocation</field><field name="view_mode">form</field><field name="view_ids" eval="[(5, 0, 0), (0, 0, {'view_mode': 'form', 'view_id': ref('hr_leave_allocation_overtime_view_form')})]"/><field name="target">new</field>
</record>
又他们碰到eval了,这是啥意思呢?
注意 :
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">tree</field><field name="view_id" ref="view_test_tree"/><field name="act_window_id" ref="test_action"/>
</record>
这里有个实际的例子
<record id="hr_expense_actions_all" model="ir.actions.act_window">
<field name="name">Expenses Analysis</field>
<field name="res_model">hr.expense</field>
<field name="view_mode">graph,pivot,tree,form</field>
<field name="search_view_id" ref="hr_expense_view_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_empty_folder">
No data yet!
</p><p>
Create new expenses to get statistics.
</p>
</field>
</record><record id="hr_expense_actions_all_graph" model="ir.actions.act_window.view">
<field name="view_mode">graph</field>
<field name="view_id" ref="hr_expense.hr_expense_view_graph"/>
<field name="act_window_id" ref="hr_expense_actions_all"/>
</record><record id="hr_expense_actions_all_pivot" model="ir.actions.act_window.view">
<field name="view_mode">pivot</field>
<field name="view_id" ref="hr_expense.hr_expense_view_pivot"/>
<field name="act_window_id" ref="hr_expense_actions_all"/>
</record><record id="hr_expense_actions_all_tree" model="ir.actions.act_window.view">
<field name="view_mode">tree</field>
<field name="view_id" ref="hr_expense_view_expenses_analysis_tree"/>
<field name="act_window_id" ref="hr_expense_actions_all"/>
</record>
view_id
指定一个特定的视图id, 它的类型在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 "视图,即使那不是模型的默认视图。
视图序列的服务器端组成如下:
- 从view_ids中获取each (id, type)(按顺序排序)
- 如果view_id已经定义,并且它的类型还没有被填充,那么就添加它的(id, type)
- 对于view_mode中每个未填充的类型,append (False, type)
view_ids, view_id,view_mode 最终目的都是为了生成views, 也就是视图.
模型是死的,像男人,一成不变
视图像女人,千变万化, 姿态万千
一阴一阳之谓道,设计之美又在这里得到了体现
3 URL动作(ir.actions.act_url)
允许通过Odoo操作打开URL(网站/网页)。可以通过两个字段进行定制:
3.1 url
动作时要打开的地址
3.2 target:
- new 在新窗口/页面中打开该地址(默认值)
- self 将当前内容替换为该页
{"type": "ir.actions.act_url","url": "https://odoo.com","target": "self",
}
4 服务器动作(ir.actions.server)
class odoo.addons.base.models.ir_actions.IrActionsServer(env, ids, prefetch_ids)[source]
服务器端的动作。服务器动作在基本模型上工作,并提供可以自动执行的各种类型的操作,例如使用基本操作规则,或者通过在“More”上下文菜单中手动添加操作。
从Odoo 8.0开始,在操作表单视图上增加了一个“创建菜单操作”按钮。它在基本模型的More菜单中创建了一个条目。这允许创建服务器操作并通过界面轻松地在批量模式下运行它们。
fatux: 没见过
可用的操作有:
- ’ Execute Python Code ':将被执行的Python代码块
- ’ Create a new Record ':用新值创建一个新记录
- ’ Write on a Record ':更新记录的值
- ’ Execute几个动作’:定义一个触发其他几个服务器动作的动作
允许从任何有效的操作位置触发复杂的服务器代码。只有两个字段与客户端相关:
id: 要执行的服务器端动作的在数据库中的ID
context
(optional)
运行服务器操作时要使用的上下文数据
数据库内的记录非常丰富,可以根据它们的状态执行许多特定或通用的操作。一些字段(和相应的行为)在状态之间是共享的:
model_id 链接到动作的Odoo模型。
state:
- code:执行通过code参数给出的python代码。
- object_create:根据fields_lines规范创建一个新的模型crud_model_id记录。
- object_write:根据fields_lines规范更新当前记录
- multi:执行通过child_ids参数给出的几个动作。
4.2 State fields
根据其状态,行为通过不同的字段定义。每个字段后面都给出了相关的状态。
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
(create)(required)
在其中创建新记录的模型
link_field_id
(create)
Many2one 到ir.model.fields,指定当前记录的m2o字段,新创建的记录应该设置在该字段上(模型应该匹配)。
fields_lines
(create/write)
创建或复制记录时重写的字段。One2many 有如下字段:
col1
在相关模型中设置的Ir.model.fields (crud_model_id用于创建,model_id用于更新)
value
字段的值,通过类型解释
type
(value|reference|equation)
value :value字段被解释为文字值(可能被转换)
equation: value字段被解释为Python表达式并求值
reference: ?
child_ids
(multi)
指定要在multi状态中执行的多个子操作(ir.actions.server)。如果子操作本身返回操作,则最后一个操作将作为multi自己的下一个操作返回给客户端
Evaluation context
在服务器动作的表达式上下文中有许多可用的key:
- model: 通过model_id链接到操作的模型对象
- Record /records :触发动作的Record /records,t可以为空。
- env Odoo环境
- datetime, dateutil, time, timezone对应的Python模块
- Log: Log (message, level=‘info’)日志功能,记录调试信息。日志表
- Warning异常的警告构造函数
fatux: 终于整理完了,感觉挺乱的,没怎么理明白,以后碰到实际案例再说吧
5 报表动作(ir.actions.report)
触发报表的打印。 在form视图的打印菜单里
如果您通过而不是标记定义报表,并且希望操作显示在模型视图的Print菜单中,那么您还需要从Bindings中指定binding_model_id。没有必要将binding_type设置为report,因为ir.actions.report将隐式默认为该值。
5.1 name
(mandatory)
未指定print_report_name时用作文件名。否则,当在某种类型的列表中查找报表时,仅作为助记符/描述有用
5.2 model
(mandatory)
你的报告将涉及的模型
5.3 report_type
(default=qweb-pdf)
PDF报告使用qweb-pdf, HTML报告使用qweb-html
5.4 report_name
(mandatory)
用于呈现报告的qweb模板的名称(外部id)
5.5 print_report_name
定义报表名称的Python表达式。
5.6 groups_id
Many2many字段到允许查看/使用当前报表的组
5.7 multi
如果设置为True,则该操作将不会显示在表单视图上。
5.8 paperformat_id
Many2one
字段转换为您希望用于此报告的纸张格式(如果未指定,将使用公司格式)。
5.9 attachment_use
如果设置为True,则报告只在第一次请求时生成一次,然后从存储的报告中重新打印,而不是每次都重新生成。
5.10 attachment
定义报表名称的Python表达式;record 可以作为变量对象访问
6 客户端动作(ir.actions.client)
触发一个完全在客户端实现的操作。
6.1 tag
操作的客户端标识符,一个客户端应该知道如何做出反应的任意字符串
6.2 params
(optional)
与客户端动作标记一起发送给客户端的附加数据的Python字典
6.3 target
(optional)
- current: 当前主内容区域
- fullscreen: 全屏
- new: 对话框/弹窗
- main: 代替current, 清除面包屑导航
默认值是current
{"type": "ir.actions.client","tag": "pos.ui"
}
告诉客户端启动销售点接口,服务器不知道POS接口是如何工作的。
7 定时任务(ir.cron)
动作在预定义的频率上自动触发。
- name : 自动动作的名称(主要用于日志显示)
- interval_number: 两次执行操作之间的interval_type uom数
- interval_type:频率间隔的测量单位(minutes
,
hours,
days,
weeks,
months) - numbercall:此操作运行的次数。如果期望该操作无限期地运行,则设置为-1。
- doall:布尔值, 表示在服务器重启的情况下是否必须执行错过的操作。
- model_id: 将调用此操作的模型
- code:操作的代码内容。可以是对模型方法的简单调用:
- nextcall: 此操作的下一个计划执行日期(日期/时间格式)