Odoo自定义视图创建报错:Uncaught Promise > No view found for act_window action 139
Odoo 自定义视图报错:Uncaught Promise > No view found for act_window action 139 解决方法及Odoo16示例
问题描述
作为Odoo开发新手,尝试从零创建自定义视图,因官方文档晦涩难懂,跟着《Odoo Experience 2018 - How to Create a New View》视频操作,但打开模块时触发报错:Uncaught Promise > No view found for act_window action 139,不清楚act_window action ID未找到的原因,寻求解决方法或Odoo 16中创建自定义视图的完整示例。
用户提供的原始代码如下:
manifest.py
{ 'name': "Hello World", 'summary': "Say Hello", 'description': """ Say Hellow to the world """, 'version': '0.1', 'depends': ['web', 'contacts', 'base_geolocalize'], 'data': [ "views/data.xml" ], 'assets': { 'web.assets_backend': [ 'hello_world_view/static/src/js/hello_world_view.js', 'hello_world_view/static/src/scss/hello_world_view.scss', ], }, 'installable': True, 'auto_install': True }
ir_action.py
from odoo import models, fields class ActionWindow(models.Model): _inherit = 'ir.actions.act_window.view' view_mode = fields.Selection( selection_add=[('hello_world', "Hello World")], ondelete={'hello_world': 'cascade'} )
ir_ui_view.py
class View(models.Model): _inherit = 'ir.ui.view' type = fields.Selection( selection_add=[('hello_world', "Hello World")] )
hello_world_view.js
odoo.define('hello_world_view.HelloWorldView', function (require) { "use strict"; var AbstractAction = require('web.AbstractAction'); var core = require('web.core'); var QWeb = core.qweb; var HelloWorldView = AbstractAction.extend({ template: 'HelloWorldTemplate', init: function (parent, options) { this._super.apply(this, arguments); this.data = options.data; }, }); core.action_registry.add('hello_world_view', HelloWorldView); return HelloWorldView; });
data.xml
<?xml version="1.0" encoding="UTF-8"?> <odoo> <record model="ir.ui.view" id="hello_world_view_1"> <field name="model">res.partner</field> <field name="mode">primary</field> <field name="arch" type="xml"> <hello_world> </hello_world> </field> </record> <record model="ir.actions.act_window" id="first_hello_world_view"> <field name="name">Hello World</field> <field name="res_model">res.partner</field> <field name="view_mode">hello_world</field> <field name="view_id" ref="hello_world_view_1"/> </record> <record model="ir.actions.act_window" id="second_hello_world_view"> <field name="name">Hello World</field> <field name="res_model">res.partner</field> <field name="view_mode">tree,form</field> <!-- <field name="view_id" ref="hello_world_view_2"/>--> </record> <menuitem id="main_hello_world_menu" name="Hello World App"/> <menuitem id="hello_world_submenu" name="Hello World Menu" parent="main_hello_world_menu"/> <menuitem id="open_view" name="Open Hello World View" parent="hello_world_submenu" action="first_hello_world_view"/> </odoo>
错误原因分析
- 视图类型未指定:XML中的
ir.ui.view记录缺少type="hello_world"字段,Odoo无法识别该视图属于自定义的视图类型。 - 视图与动作混淆:JS中错误地继承
AbstractAction并注册到action_registry,但自定义视图属于Odoo的视图体系,应继承AbstractView并注册到viewRegistry。 - 模板缺失:JS引用了
HelloWorldTemplate但未定义对应的XML模板文件,导致渲染失败。
解决方案及完整Odoo16示例
以下是修正后的完整Odoo16自定义视图实现:
1. 模块结构
hello_world_view/ ├── __init__.py ├── __manifest__.py ├── models/ │ ├── __init__.py │ ├── ir_action.py │ └── ir_ui_view.py ├── static/ │ └── src/ │ ├── js/ │ │ └── hello_world_view.js │ ├── scss/ │ │ └── hello_world_view.scss │ └── xml/ │ └── hello_world_template.xml └── views/ └── data.xml
2. 各文件代码
manifest.py
{ 'name': "Hello World 自定义视图", 'summary': "Odoo16自定义视图演示", 'description': "实现一个简单的自定义视图,展示Hello World内容", 'version': '1.0', 'depends': ['web', 'contacts'], 'data': [ "views/data.xml" ], 'assets': { 'web.assets_backend': [ 'hello_world_view/static/src/js/hello_world_view.js', 'hello_world_view/static/src/scss/hello_world_view.scss', 'hello_world_view/static/src/xml/hello_world_template.xml', ], }, 'installable': True, 'auto_install': False, 'application': True, }
models/init.py
from . import ir_action from . import ir_ui_view
models/ir_action.py
from odoo import models, fields class ActionWindowView(models.Model): _inherit = 'ir.actions.act_window.view' view_mode = fields.Selection( selection_add=[('hello_world', "Hello World")], ondelete={'hello_world': 'cascade'} )
models/ir_ui_view.py
from odoo import models, fields class View(models.Model): _inherit = 'ir.ui.view' type = fields.Selection( selection_add=[('hello_world', "Hello World 视图")] )
static/src/js/hello_world_view.js
odoo.define('hello_world_view.HelloWorldView', function (require) { "use strict"; const AbstractView = require('web.AbstractView'); const viewRegistry = require('web.view_registry'); const core = require('web.core'); const QWeb = core.qweb; const HelloWorldView = AbstractView.extend({ display_name: 'Hello World 视图', icon: 'fa-smile-o', template: 'HelloWorldTemplate', init: function (viewInfo, params) { this._super.apply(this, arguments); this.modelName = params.modelName; }, _render: function () { this.$el.html(QWeb.render('HelloWorldTemplate', { model: this.modelName, message: 'Hello World! 这是你的第一个Odoo自定义视图' })); }, }); viewRegistry.add('hello_world', HelloWorldView); return HelloWorldView; });
static/src/xml/hello_world_template.xml
<?xml version="1.0" encoding="UTF-8"?> <templates xml:space="preserve"> <t t-name="HelloWorldTemplate"> <div class="oe_hello_world_view p-4"> <div class="alert alert-success"> <h1 class="mb-4"><t t-esc="message"/></h1> <p class="lead">当前关联模型:<strong><t t-esc="model"/></strong></p> </div> </div> </t> </templates>
views/data.xml
<?xml version="1.0" encoding="UTF-8"?> <odoo> <!-- 注册自定义视图 --> <record model="ir.ui.view" id="hello_world_view_partner"> <field name="name">res.partner.hello_world</field> <field name="model">res.partner</field> <field name="type">hello_world</field> <field name="arch" type="xml"> <hello_world/> </field> </record> <!-- 创建视图动作 --> <record model="ir.actions.act_window" id="action_hello_world_partner"> <field name="name">Hello World 视图</field> <field name="res_model">res.partner</field> <field name="view_mode">hello_world</field> <field name="view_id" ref="hello_world_view_partner"/> </record> <!-- 菜单配置 --> <menuitem id="menu_hello_world_root" name="Hello World 应用" sequence="10"/> <menuitem id="menu_hello_world_sub" name="自定义视图演示" parent="menu_hello_world_root"/> <menuitem id="menu_open_hello_world" name="打开Hello视图" parent="menu_hello_world_sub" action="action_hello_world_partner"/> </odoo>
关键修复点说明
- 视图注册修正:JS中改为继承
AbstractView并注册到viewRegistry,让Odoo识别这是一个视图类型而非独立动作。 - 视图类型指定:在XML的
ir.ui.view记录中添加type="hello_world",与自定义视图类型匹配。 - 模板定义:新增XML模板文件并添加到assets加载列表,确保JS能找到渲染模板。
- 模块配置优化:关闭
auto_install并设置application=True,避免模块自动安装导致的冲突。
内容的提问来源于stack exchange,提问作者Riajul Kashem
相关产品推荐
相关产品推荐

