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

Odoo16中JavaScript调用RPC读取记录失败问题排查

Odoo网站模板中JS RPC调用失效的排查及替代方案

先排查RPC调用的核心问题

你能拿到选中项ID但RPC不生效,大概率是格式、权限或环境问题,按下面步骤逐一排查:

1. 核对RPC调用的基础格式

Odoo的JS RPC必须严格遵循规范,下面是标准的read方法调用示例,对照你的代码检查:

// 确保代码放在Odoo环境就绪后执行
odoo.ready(function() {
    document.getElementById('your-select-id').addEventListener('change', function(e) {
        const selectedId = parseInt(e.target.value);
        if (!selectedId) return;

        odoo.rpc.query({
            model: 'project.initiative', // 替换为你的initiative对应模型(必须和后台完全一致)
            method: 'read',
            args: [[selectedId], ['name', 'description', 'your_other_fields']] // 第一个元素是ID数组,第二个是要获取的字段列表
        }).then(result => {
            if (result.length) {
                const initiative = result[0];
                // 把详情渲染到页面,比如插入到指定容器
                document.getElementById('detail-box').innerHTML = `
                    <h4>${initiative.name}</h4>
                    <p>${initiative.description || '暂无描述'}</p>
                `;
            }
        }).catch(err => {
            // 一定要打开浏览器控制台看错误信息,这是排查关键
            console.error('RPC调用失败:', err);
        });
    });
});

重点检查:

  • model名称是否拼写错误(比如后台是project.initiative,你写成了initiative)
  • args的格式:必须是二维数组,ID要放在数组里,字段列表不能漏
  • 控制台是否有报错(比如模型不存在、权限不足、字段不存在等)

2. 验证用户权限

网站默认的Public用户组通常没有很多模型的读取权限,这是RPC失败的常见原因:

  1. 登录Odoo后台,找到你的initiative模型
  2. 进入「设置」→「权限」,找到对应权限组
  3. 给Public组添加「读取」权限,或者创建专门的网站用户组并分配权限

3. 确保代码在Odoo环境就绪后执行

如果你的JS代码加载过早,Odoo的odoo.rpc对象还没初始化,自然调用失败。必须把代码放在odoo.ready()回调里,像上面示例那样。


其他获取记录的替代方式

如果RPC调用实在搞不定,可以试试下面几种方法:

1. 预存详情到下拉选项的Data属性

如果initiative的数量不多,直接在渲染下拉框时把记录详情存在option的data属性里,选中时直接读取,不用发请求:
QWeb模板代码:

<select id="initiative-select">
    <t t-foreach="initiative_records" t-as="init">
        <option 
            t-att-value="init.id" 
            t-att-data-details='JSON.stringify(init)'
        >
            <t t-esc="init.name"/>
        </option>
    </t>
</select>

JS代码:

odoo.ready(function() {
    document.getElementById('initiative-select').addEventListener('change', function(e) {
        const selectedOption = e.target.options[e.target.selectedIndex];
        if (!selectedOption.dataset.details) return;
        
        const details = JSON.parse(selectedOption.dataset.details);
        // 直接渲染详情
        document.getElementById('detail-box').innerHTML = `<h4>${details.name}</h4><p>${details.description}</p>`;
    });
});

2. 自定义网站控制器(Python+Fetch)

自己写一个网站路由,返回记录详情,用JS的Fetch API调用:
后台Python代码:

from odoo import http
from odoo.http import request

class InitiativeDetailController(http.Controller):
    @http.route('/get-initiative-detail/<int:init_id>', type='json', auth='public')
    def get_initiative_detail(self, init_id):
        # 用sudo()确保Public用户能访问,也可以加权限验证逻辑
        initiative = request.env['project.initiative'].sudo().browse(init_id)
        if initiative.exists():
            return {
                'name': initiative.name,
                'description': initiative.description,
                'create_date': initiative.create_date.strftime('%Y-%m-%d')
            }
        return {}

JS代码:

odoo.ready(function() {
    document.getElementById('initiative-select').addEventListener('change', function(e) {
        const initId = parseInt(e.target.value);
        if (!initId) return;

        fetch(`/get-initiative-detail/${initId}`)
            .then(res => res.json())
            .then(data => {
                if (data.name) {
                    document.getElementById('detail-box').innerHTML = `<h4>${data.name}</h4><p>${data.description}</p>`;
                }
            })
            .catch(err => console.error('获取详情失败:', err));
    });
});

3. 使用旧版Web Model(适合Odoo 10-12)

如果是较旧的Odoo版本,可以用web.Model来调用:

odoo.ready(function() {
    const InitiativeModel = new odoo.web.Model('project.initiative');
    document.getElementById('initiative-select').addEventListener('change', function(e) {
        const initId = parseInt(e.target.value);
        if (!initId) return;

        InitiativeModel.call('read', [[initId], ['name', 'description']])
            .then(result => {
                // 处理结果
            })
            .catch(err => console.error(err));
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:43:28