Odoo 在action的domain和context中使用self.env
场景:
数据筛选的时候,希望通过当前登录人的公司地域信息,来限制数据的查看。所以我希望直接在action中的domain中直接通过self来获取地域信息,很遗憾,self是未定义的。
思考:
odoo在进入一个页面的tree视图的时候,肯定也是要去读取action中的domain信息的,是不是可以尝试在odoo读取到domain信息的时候,直接将我写的条件转化为一个对象的id,而不是变量
实现:
根据研究后发现,路由层通过@http.route('/web/action/load', type='json', auth="user")
,进入到odoo后端,
再通过action = request.env[action_type].browse([action_id]).read()
的read方法,拿到了最终的展示数据,所以我需要在read方法进入之前,通过上下文做一个标志(EnvParamenter)
# 此处是修改了odoo12的源码
@http.route('/web/action/load', type='json', auth="user")
def load(self, action_id, additional_context=None):
Actions = request.env['ir.actions.actions']
value = False
try:
action_id = int(action_id)
except ValueError:
try:
action = request.env.ref(action_id)
assert action._name.startswith('ir.actions.')
action_id = action.id
except Exception:
action_id = 0 # force failed read
base_action = Actions.browse([action_id]).read(['type'])
if base_action:
ctx = dict(request.context)
action_type = base_action[0]['type']
if action_type == 'ir.actions.report':
ctx.update({'bin_size': True})
if additional_context:
ctx.update(additional_context)
request.context = ctx
if action_type == 'ir.actions.act_window':
action = request.env[action_type].browse([action_id]).with_context(EnvParameter=True).read()
else:
action = request.env[action_type].browse([action_id]).read()
if action:
value = clean_action(action[0])
return value
然后继承ir.actions.act_window
模型
@api.multi
def read(self, fields=None, load='_classic_read'):
# 继承read方法,使action中的domain和context 可以读取 self.env 对象内容
result = super(FrIrActionsActWindowModel, self).read(fields, load)
for values in result:
if self._context.get('EnvParameter', False):
if values['domain'] and 'self.env' in values['domain']:
values['domain'] = str(eval(values['domain']))
if values['context'] and 'self.env' in values['context']:
values['context'] = str(eval(values['context']))
return result