Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return an existing ir.actions.act_window from Python in Odoo 10?

What I need

If the user clicks on my button, take him to different views of different models depending on a field of the current record.

What I did

I have declared a type object button to call a Python method. Inside it, I check the field. If its value is A, I redirect him to the model X and if its value is B, I redirect him to the model Y.

The code

@api.multi
def my_button_method(self):
    self.ensure_one()
    if self.my_field == 'A':
        action_id = self.env.ref(
            'my_module.my_ir_actions_act_window_A')
        return action_id.__dict__
    elif self.my_field == 'B':
        action_id = self.env.ref(
            'my_module.my_ir_actions_act_window_B')
    else:
        action_id = False
    if action_id:
        return action_id.__dict__

If I write this after the definition of action_id:

_logger.info(action_id.name)
_logger.info(action_id.type)
_logger.info(action_id.res_model)
_logger.info(action_id.view_type)
_logger.info(action_id.view_mode)
_logger.info(action_id.search_view_id)
_logger.info(action_id.help)

I get the right values. So, after googling I saw that __dict__ gives you a dictionary whose keys are the attributes of the object and whose values the values of those attributes.

But the code is giving an error because action_id.__dict__ doesn't return a dictionary with the expected attributes of the action and its values, but the following instead:

{
    '_prefetch': defaultdict(
        <type 'set'>,
        {
            'ir.actions.act_window': set([449])
        }
    ),
    'env': <odoo.api.Environment object at 0x7f0aa7ed7cd0>,
    '_ids': (449,)
}

Can anyone tell me why? I'm trying to avoid this code:

@api.multi
def my_button_method(self):
    self.ensure_one()
    if self.my_field == 'A':
        action_id = self.env.ref(
            'my_module.my_ir_actions_act_window_A')
    elif self.my_field == 'B':
        action_id = self.env.ref(
            'my_module.my_ir_actions_act_window_B')
    else:
        action_id
    if action_id:
        return {
            'name': action_id.name,
            'type': action_id.type,
            'res_model': action_id.res_model,
            'view_type': action_id.view_type,
            'view_mode': action_id.view_mode,
            'search_view_id': action_id.search_view_id,
            'help': action_id.help,
        }

May be there is a much better solution using a server action, if so, does anyone know how?

like image 346
forvas Avatar asked Dec 23 '22 07:12

forvas


1 Answers

You can do the really short "style":

action = self.env.ref('my_module.my_ir_actions_act_window_A').read()[0]
return action

You will find a lot of examples this "style" around in Odoo code.

Edit: that should also work in Odoo 7-14

like image 195
CZoellner Avatar answered Dec 28 '22 11:12

CZoellner