-
~/cli/server.py, ln 320, main(args) -
~/cli/server.py, ln 366, openerp.service.start_services_workers() 或 openerp.service.start_services() -
以
-
start_internal() 1.1 openerp.osv.osv.start_object_proxy() 1.2 web_services.start_service() 1.3 load_server_wide_modules(),openerp.modules.module.load_openerp_module 1.4 加载
web后会通过postload去执行 openerp.addons.web.http.wsgi_postload 1.5 在初始化的过程中会更新openerp.addons.web.http里的addons_module,addons_manifest,controllers_class,controllers_class_path,controllers_object,controllers_object_path, controllers_path 这些全局可见的变量,魔改的想象空间很大 1.6openerp.wsgi.register_wsgi_handler(Root())生成一个 wsgi app 并注册,实际的 app 是 Root.dispatch 1.7Root.__init__会self.load_addons,凡是在路径下的所有 addon 都会被加载,也就是说所有语句都会被执行,好可怕 1.8_cp_path相当于 Blueprint,其后的部分匹配为 method 1.9 没有区分 GET POST 等,而且按照注释看来,无论参数都会被统一处理到同一个地方 -
wsgi_server.start_service()
-
cron.start_service()
通过多进程起的,暂时没有打到断点
- 当前用户使用的语言
_oe_instance.session.user_context.lang
-
对于
oe 网页服务来说,base不是基础模块,web才是(cli的情况不清楚) 1.1 更确切的说,默认值是 ['web', 'web_kanban'] // ~/openerp/tools/config.py, line 526 -
加载过程的主要代码在
~/openerp/addons/web/controllers/main.py, line 247, module_boot及相关代码 2.1. 首先加载网页服务的基础模块,然后加载本数据库中已安装的addons2.2.网页服务的基础模块,即['web', 'web_kanban']确定是最先加载的 2.3. 已安装的addons按照依赖关系,最终的加载顺序是按照 Topsort 排序的结果;该排序的结果是是“被依赖模块”确定在“依赖模块”的前面;但考虑到复杂的深层依赖关系,以及实际安装addon的顺序不同,这个排序的结果实际上是不稳定的;也就是说除了好好分析依赖关系和写清楚依赖关系,没有其它途径可以预期最终的加载行为 -
然后根据
addon的顺序,以及addon内__openerp__.py中写清楚的静态文件加载顺序进行依次加载 3.1 如果AddonA依赖于AddonB,那么AddonB中设定的js, css全部在AddonA之前加载 3.2 如果在AddonA中设定'js': ['1.js', '2.js'],那么1.js在2.js之前加载 -
最终的模块加载效果可以在
window.openerp.instances.instance0里查看 -
不是所有已安装的模块都会被“加载”,比如
product就不会出现在上面这个列表里
-
官方的原生视图包括
tree/list,form;kanban是扩展出来的,所以如果要自定义视图,主要参考kanban的实现 -
主要需要
override的属性和方法如下(命名规则随手写的,不保证对):instance.nt_my_addon.CustomView = instance.web.View.extend({ searchable: false, template: 'nt_my_addon.custom_view_tpl', display_name: 'Custom View', view_type: 'custom_view', init: function (parent, dataset, view_id, options) {}, start : function () { // 不要去 call this._super,完全自己控制 }, do_show: function () { // 详见 nt_bwk_flowchart this._super.apply(this, arguments); }, destroy: function () { }, }); instance.web.views.add('CustomView', 'instance.nt_my_addon.CustomeView'); -
原始菜单一般会指向 tree view,并且不知道 custom view 的存在,因此需要自定义菜单,并覆盖或隐藏掉原始菜单
<record id="nt_my_addon_custom_view" model="ir.ui.view"> <field name="name">nt.my_addon.custom_view</field> <field name="model">model.to.display</field> </record> <record id="nt_my_addon_tree_action"> <field name="name">Model Name</field> <field name="type">ir.actions.act_window</field> <field name="res_model">model.to.display</field> <field name="view_type">form</field> <field name="view_mode">tree,form,kanban,nt_my_addon_custom_view</field> </record> <menuitem name="Model Name" id="nt_my_addon_model_name" parent="nt_my_addon_root" action="nt_my_addon_tree_action" /> -
以
FormView为例:- 在视图之间切换的时候,首先调用基类
instance.web.view的switch_mode方法,目的是做lazy loading;完成后调当前类的do_show方法;获取数据后调用当前类的load_record - 在记录之间切换的时候,首先调用当前类的
execute_pager_action方法,然后调用reload,获取数据后调用load_record - 上述调用都是用的
event dispatcher,不知道为什么;可能是Backbone的编码风格
- 在视图之间切换的时候,首先调用基类
-
官方接口提供了基于后端
ORM的语义化查询,返回值是基于jQuery的Deferred(没细看版本,反正要重新封装)var _adapter = new oe_instance.web.Model('res.users'); _adapter .query(['name', 'login', 'user_email', 'signature']) .filter(['active', '=', true], ['company_id', '=', main_company]]) .limit(15) .all() .then(function (data) { // }); -
或者直接调用
Model上的方法_adapter .call('change_password', ['oldpassword', 'newpassword'], { context: some_context }) .then(function (data) { // }); // 相当于后端的 user_obj = self.pool.get('res.user') user_obj.change_password(cr, uid, oldpassword, newpassword, context=some_context) -
当前的
contextvar _context = _adapter.context();
参考:
####do_action(action, options)
/addons/web/static/src/js/views.js line 295
-
假如不传参数,那么默认行为是
ir.actions.act_window_close -
假如你知道要跳转到哪 个
action,直接跳id是最准确的,得到的是identical的结果 oe_this.do_action('base.action_partner_form') -
对于
dialog,可以在options里面设定on_close方法,没有传入值oe.this.do_action(action, { on_close: function () { console.assert(arguments.length === 0); } })
参考:
- (official) OpenERP Web Components - The Action Manager