odoo联系人相关的信息全部存储在res.partner对象里,包括供应商、客户、员工等个人及公司相关的信息都可以归纳入内
1 |
partner_id = fields.Many2one('res.partner', required=True) |
二次开发经常会直接关联该对象可以少造很多轮子,但由于其新建联系人的默认视图view_partner_form是一个非常重且包含好多类型设置又被各种业务模块继承扩展过的大视图,这就需要为不同的应用场景开发对应业务信息的轻量级自定义视图
最开始我是从继承res.partner并重写其@api.model的fields_view_get方法来完成的
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@api.model def fields_view_get(self, view_id=None, view_type=False, toolbar=False, submenu=False): def get_view_id(name): view = self.env['ir.ui.view'].search([('name', '=', name)], limit=1) if not view: return None return view.id context_view_name = self._context.get('view_name') if context_view_name: ##重置context指定视图 view_id = get_view_id(context_view_name) return super(res_partner, self).fields_view_get( view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) |
使用很简单view context新增一个view_name属性指定自定义视图名称即可
1 |
<field name="partner_id" context="{'view_name': 'res.partner.daybook.form'}"/> |
当后来对其它对象也有同样需求的时候就基本确定我悲剧的造了一个小轮子
因为这个需求是非常合理,如果要一个个对象去继承重写是非常不实现的,至少也要在共同的父类上做对接
根据这个思路从openerp.osv.Model一直寻找到openerp.models.Model的fields_view_get父级方法,其中有一段代码让人眼前一亮
1 2 3 4 5 6 7 8 9 10 11 12 |
# try to find a view_id if none provided if not view_id: # <view_type>_view_ref in context can be used to overrride the default view view_ref_key = view_type + '_view_ref' view_ref = context.get(view_ref_key) if view_ref: if '.' in view_ref: module, view_ref = view_ref.split('.', 1) cr.execute("SELECT res_id FROM ir_model_data WHERE model='ir.ui.view' AND module=%s AND name=%s", (module, view_ref)) view_ref_res = cr.fetchone() if view_ref_res: view_id = view_ref_res[0] |
这不就是传说中解决分类自选视图的相关代码:类型、模块名、视图ID确定一个视图
马上删除之前所有相关代码,view context按如下规则修改直接应用
1 |
<field name="partner_id" context="{'form_view_ref': '模块名.视图ID'}"/> |
至此,对odoo一切都是models的理念又有了进一步的理解