动作的加载:

刷新视图页面执行load_views方法

/web/dataset/call_kw/model_name/load_views

在odoo/models.py的BaseModel中有一个load_views方法

@api.model
def load_views(self, views, options=None):
""" Returns the fields_views of given views, along with the fields of
the current model, and optionally its filters for the given action. :param views: list of [view_id, view_type]
:param options['toolbar']: True to include contextual actions when loading fields_views
:param options['load_filters']: True to return the model's filters
:param options['action_id']: id of the action to get the filters
:return: dictionary with fields_views, fields and optionally filters
"""
options = options or {}
result = {} toolbar = options.get('toolbar')
result['fields_views'] = {
v_type: self.fields_view_get(v_id, v_type if v_type != 'list' else 'tree',
toolbar=toolbar if v_type != 'search' else False)
for [v_id, v_type] in views
}
result['fields'] = self.fields_get() if options.get('load_filters'):
result['filters'] = self.env['ir.filters'].get_filters(self._name, options.get('action_id')) return result

odoo/models.py

@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
""" fields_view_get([view_id | view_type='form']) Get the detailed composition of the requested view like fields, model, view architecture :param view_id: id of the view or None
:param view_type: type of the view to return if view_id is None ('form', 'tree', ...)
:param toolbar: true to include contextual actions
:param submenu: deprecated
:return: dictionary describing the composition of the requested view (including inherited views and extensions)
:raise AttributeError:
* if the inherited view has unknown position to work with other than 'before', 'after', 'inside', 'replace'
* if some tag other than 'position' is found in parent view
:raise Invalid ArchitectureError: if there is view type other than form, tree, calendar, search etc defined on the structure
"""
View = self.env['ir.ui.view'] # Get the view arch and all other attributes describing the composition of the view
result = self._fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) # Override context for postprocessing
if view_id and result.get('base_model', self._name) != self._name:
View = View.with_context(base_model_name=result['base_model']) # Apply post processing, groups and modifiers etc...
xarch, xfields = View.postprocess_and_fields(self._name, etree.fromstring(result['arch']), view_id)
result['arch'] = xarch
result['fields'] = xfields # Add related action information if aksed
if toolbar:
bindings = self.env['ir.actions.actions'].get_bindings(self._name)
resreport = [action
for action in bindings['report']
if view_type == 'tree' or not action.get('multi')]
resaction = [action
for action in bindings['action']
if view_type == 'tree' or not action.get('multi')]
resrelate = []
if view_type == 'form':
resrelate = bindings['action_form_only'] for res in itertools.chain(resreport, resaction):
res['string'] = res['name'] result['toolbar'] = {
'print': resreport,
'action': resaction,
'relate': resrelate,
}
return result

addons/base/models/ir_actions.py

@api.model
@tools.ormcache('frozenset(self.env.user.groups_id.ids)', 'model_name')
def get_bindings(self, model_name):
""" Retrieve the list of actions bound to the given model. :return: a dict mapping binding types to a list of dict describing
actions, where the latter is given by calling the method
``read`` on the action record.
"""
cr = self.env.cr
query = """ SELECT a.id, a.type, a.binding_type
FROM ir_actions a, ir_model m
WHERE a.binding_model_id=m.id AND m.model=%s
ORDER BY a.id """
cr.execute(query, [model_name]) # discard unauthorized actions, and read action definitions
result = defaultdict(list)
user_groups = self.env.user.groups_id
for action_id, action_model, binding_type in cr.fetchall():
try:
action = self.env[action_model].browse(action_id)
action_groups = getattr(action, 'groups_id', ())
if action_groups and not action_groups & user_groups:
# the user may not perform this action
continue
result[binding_type].append(action.read()[0])
except (AccessError, MissingError):
continue return result

能否通过修改ir.actions.server的表结构,增加binding_view_id字段,动作定义时设置binding_view_id字段,实现相同模型不同视图显示不通的动作内容。

1、在ir.actions.server中增加字段

binding_view_id = fields.Char(string='my char', default='99999999999')
2、在服务器定义中设置字段
<record id="action_XXX_audit_server" model="ir.actions.server" >
<field name="name">Audit</field>
<field name="model_id" ref="model_gl_voucher"/>
<field name="type">ir.actions.server</field>
<field name="state">code</field>
<field name="code">
action = records.action_server_run()
</field>
<field name="binding_model_id" ref="model_XXX" />
<field name="binding_view_id">66666666666</field>
</record>

3、查看数据库

已经写到数据库了,所以在 get_bindings中加载动作时增加一层过滤就OK,这样就可以实现相同model,相同视图类型,不同视图,显示不同action。

动作的执行:

addons/web/controllers/main.py

@http.route('/web/action/run', type='json', auth="user")
def run(self, action_id):
result = request.env['ir.actions.server'].browse([action_id]).run()
return clean_action(result) if result else False

addons/base/models/ir_actions.py 

@api.multi
def run(self):
""" Runs the server action. For each server action, the
run_action_<STATE> method is called. This allows easy overriding
of the server actions. :param dict context: context should contain following keys - active_id: id of the current object (single mode)
- active_model: current model that should equal the action's model The following keys are optional: - active_ids: ids of the current records (mass mode). If active_ids
and active_id are present, active_ids is given precedence. :return: an action_id to be executed, or False is finished correctly without
return action
"""
res = False
for action in self:
eval_context = self._get_eval_context(action)
if hasattr(self, 'run_action_%s_multi' % action.state):
# call the multi method
run_self = self.with_context(eval_context['env'].context)
func = getattr(run_self, 'run_action_%s_multi' % action.state)
res = func(action, eval_context=eval_context) elif hasattr(self, 'run_action_%s' % action.state):
active_id = self._context.get('active_id')
if not active_id and self._context.get('onchange_self'):
active_id = self._context['onchange_self']._origin.id
if not active_id: # onchange on new record
func = getattr(self, 'run_action_%s' % action.state)
res = func(action, eval_context=eval_context)
active_ids = self._context.get('active_ids', [active_id] if active_id else [])
for active_id in active_ids:
# run context dedicated to a particular active_id
run_self = self.with_context(active_ids=[active_id], active_id=active_id)
eval_context["env"].context = run_self._context
# call the single method related to the action: run_action_<STATE>
func = getattr(run_self, 'run_action_%s' % action.state)
res = func(action, eval_context=eval_context)
return res

  

odoo action的更多相关文章

  1. odoo action方法

    二.动作按钮里面也可以由字段判断: def action_select_sale_order_line(self,cr,uid,ids,date_begin,date_end,context=None ...

  2. (20)odoo中的action

    ---------更新时间18:06 2016-09-18 星期日15:05 2016-03-14 星期一18:07 2016-02-19 星期五---------* 窗口动作   <?xml ...

  3. odoo开发笔记:Server+Action服务器动作自动触发执行

           Odoo的市场定位是SME(中小型企业),这个市场的ERP产品,多如牛毛,产品各具特色.不过,Odoo的自动化处理机制,可以睥睨天下,无人能及.包括一些大型国产软件,如用友.金蝶也不具备 ...

  4. Odoo中的五种Action详解

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826232.html Odoo中的五种action都是继承自ir.actions.actions模型实现的 ...

  5. odoo view field option, action flage 参数

    options JSON object specifying configuration option for the field's widget (including default widget ...

  6. odoo开发笔记--自定义server action页面跳转注意

    场景描述: 在添加自定义服务器动作 “复制全部”后发现直接创建了新的记录,并且直接进入到form保存完的状态. 如何解决: if yourself_obj_copy: return { 'type': ...

  7. Odoo 14 Action URL 生成

    from werkzeug.urls import url_encode url = '/web#%s' % url_encode({ 'action': 'hr.plan_wizard_action ...

  8. Odoo 二次开发教程(三)-第一个Model及Form、Tree视图

    创建完我们的模块,接下来我们就要为我们的模块添加一些对象.今天我们将要创建一个学生对象(tech.student)和一些基本的属性,并将用form和tree视图将其展示出来: 一. 创建tech.st ...

  9. Defining custom settings in Odoo

    Unfortunately Odoo documentation doesn’t seem to include any information about adding new configurat ...

随机推荐

  1. 古老的txt下传和txt上载

    1.下传文件 TYPES:BEGIN OF TY_DATA, A2 TYPE CHAR20, B2 TYPE I, C2 TYPE CHAR20, END OF TY_DATA. DATA:IT_DA ...

  2. C#网页 截图

    using System.IO; using System.Drawing; using System.Drawing.Imaging; using System.Threading; using S ...

  3. linq 数据库已存在,直接添加数据

    using System.Data.Linq;using System.Data.Linq.Mapping; namespace ConsoleApplication1388{ class Progr ...

  4. 基于直接缓冲区和非直接缓冲区的javaIO文件操作

    基本概念: 1. 非直接缓冲区:  指的是通过jvm来缓存数据的,应用程序要读取本地数据要经历从本地磁盘到物理内存,然后copy到jvm中,然后再通过流的方式读取到应用程序中,写的操作正好与之相反. ...

  5. C#下的时间测试(用于计算方法执行时间)

    public class Timing { private TimeSpan m_StartTime; private TimeSpan duringTime; public Timing() //构 ...

  6. 深入浅出《设计模式》之简单工厂模式(C++)

    前言 模式介绍 简单工厂模式其实并不属于GoF23(23种设计模式),更类似工厂模式的一种变型.其定义是可以根据参数的不同返回不同类的实例.简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实 ...

  7. redis 配置及编写启动脚本

    #!/bin/sh # # Simple Redis init.d script conceived to work on Linux systems # as it does use of the ...

  8. 图解Java数据结构之单链表

    本篇文章介绍数据结构中的单链表. 链表(Linked List)介绍 链表可分为三类: 单链表 双向链表 循环列表 下面具体分析三个链表的应用. 单链表 链表是有序的列表,它在内存中存储方式如下: 虽 ...

  9. JS 判断设备来源

    1.js代码判断当前设备: function deviceType(){ var ua = navigator.userAgent; var agent = ["Android", ...

  10. liteos时间管理(九)

    1. 时间管理 1.1 概述 1.1.1 概念 时间管理以系统时钟为基础.时间管理提供给应用程序所有和时间有关的服务. 系统时钟是由定时/计数器产生的输出脉冲触发中断而产生的,一般定义为整数或长整数. ...