如何将Odoo9含ir.actions.server的自定义子菜单迁移至Odoo12?
问题原因分析
在Odoo 12中,ir.actions.server的代码执行上下文已经完全切换到了新ORM API,不再支持旧API里的self、cr(数据库游标)、uid(用户ID)、context这些变量,这就是你遇到NameError: name 'self' is not defined的核心原因。
旧版Odoo(比如9)里的服务器动作代码依赖旧API的上下文变量,但Odoo 12开始统一使用env对象来访问模型、用户、上下文等信息,原来的写法自然就失效了。
修复步骤
1. 修改服务器动作的XML代码
把原来的code字段内容替换为新API的写法,通过env来获取你的目标模型,然后调用方法:
<record id='action_menu_location_transfer_server' model='ir.actions.server'> <field name="name">Custom Transfers</field> <field name="model_id" ref="model_wizard_location_transfers_internal_transfer"/> <field name="state">code</field> <!-- 改用env获取模型并调用方法 --> <field name="code"> action = env['wizard.location.transfers.internal.transfer'].custom_get_transfer_views() </field> <field eval="True" name="condition"/> </record> <menuitem id="menu_refund_returns" name="Custom Transfers" action="action_menu_location_transfer_server" parent="stock.menu_stock_warehouse_mgmt" sequence="1" groups="base.group_user"/>
2. 适配custom_get_transfer_views方法到新API
你原来的方法是旧API风格(接收cr, uid, context参数),需要改成新API的写法,直接使用self.env来获取上下文、用户等信息:
# 旧API写法(Odoo9) def custom_get_transfer_views(self, cr, uid, context=None): # 旧逻辑代码 pass # 新API写法(Odoo12) def custom_get_transfer_views(self): # 用self.env获取上下文、用户、模型等 context = self.env.context uid = self.env.uid # 你的业务逻辑代码 # 最后返回对应的action字典,示例: return { 'type': 'ir.actions.act_window', 'name': 'Custom Transfers', 'res_model': 'your.target.model', 'view_mode': 'tree,form', # 其他必要参数... }
关键说明
- 在Odoo12的服务器动作代码中,可用的上下文变量包括
env(ORM环境)、model(当前server action关联的模型)、action(当前动作对象)等,但没有self、record、object这些旧变量,所以你之前尝试的这些都没用。 - 确保你的自定义模型
wizard.location.transfers.internal.transfer(对应XML里的model_wizard_location_transfers_internal_transfer引用)已经正确定义,并且custom_get_transfer_views方法是该模型的公共方法。
内容的提问来源于stack exchange,提问作者MouTio
相关产品推荐
相关产品推荐

