You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

错误原因分析

  1. 视图类型未指定:XML中的ir.ui.view记录缺少type="hello_world"字段,Odoo无法识别该视图属于自定义的视图类型。
  2. 视图与动作混淆:JS中错误地继承AbstractAction并注册到action_registry,但自定义视图属于Odoo的视图体系,应继承AbstractView并注册到viewRegistry。
  3. 模板缺失: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>

关键修复点说明

  1. 视图注册修正:JS中改为继承AbstractView并注册到viewRegistry,让Odoo识别这是一个视图类型而非独立动作。
  2. 视图类型指定:在XML的ir.ui.view记录中添加type="hello_world",与自定义视图类型匹配。
  3. 模板定义:新增XML模板文件并添加到assets加载列表,确保JS能找到渲染模板。
  4. 模块配置优化:关闭auto_install并设置application=True,避免模块自动安装导致的冲突。

内容的提问来源于stack exchange,提问作者Riajul Kashem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:37:02