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

Odoo 8自定义模块出现MissingError,求解决方案

Odoo 8自定义模块MissingError问题分析与解决

错误现象

在Odoo 8的自定义模块中触发MissingError,错误提示:

您尝试访问的某一文档已被删除,请刷新后重试。

完整错误栈

File "C:\Tunas_Ridean\Odoo-8.0\addons\sale\sale.py", line 1067, in product_id_change
    if product_obj.taxes_id:
  File "C:\Tunas_Ridean\Odoo-8.0\openerp\fields.py", line 840, in __get__
    return record._cache[self]
  File "C:\Tunas_Ridean\Odoo-8.0\openerp\models.py", line 6041, in __getitem__
    return value.get() if isinstance(value, SpecialValue) else value
  File "C:\Tunas_Ridean\Odoo-8.0\openerp\fields.py", line 56, in get
    raise self.exception
MissingError: ('MissingError', u'One of the documents you are trying to access has been deleted, please try again after refreshing.')

自定义模块代码

模型文件 models/sale_order.py

# models/sale_order.py
from openerp import models, fields
from openerp import api

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    product_id = fields.Many2one(
        'product.custom', string='Product', required=True,
        domain=[('state', 'in', ['confirmed', 'approved'])]
    )

    price_unit = fields.Float(
        string='Price Unit',
        related='product_id.price',  # Mengambil harga dari `product.custom`
        store=True,
        readonly=True
    )
    
    @api.onchange('product_id.price','price_unit')
    def _onchange_product_id(self):
        #import ipdb; ipdb.set_trace()
        self.price_unit = self.product_id.price
        self.name = self.product_id.description
        self.product_uom_qty = self.product_id.qty

视图文件 views/sale_order_view.xml

<!-- views/sale_order_view.xml -->
<openerp>
<data>
    <record id="view_order_form_custom" model="ir.ui.view">
        <field name="name">sale.order.form.inherit</field>
        <field name="model">sale.order</field>
        <field name="inherit_id" ref="sale.view_order_form"/>
        <field name="arch" type="xml">
            <xpath expr="//field[@name='product_id']" position="replace">
                <field name="product_id"/>
            </xpath>
            <xpath expr="//field[@name='price_unit']" position="attributes">
                <attribute name="readonly">1</attribute>
            </xpath>
        </field>
    </record>
    </data>
</openerp>

问题根源

原生sale模块的sale.order.line模型中,product_id字段关联的是product.product,且自带product_id_change方法处理产品变更逻辑。你在自定义模块中继承sale.order.line后,将product_id的关联模型替换为了product.custom,但原生的product_id_change方法仍会被触发——该方法会尝试用product.product模型去读取当前product_id对应的记录(实际是product.custom的ID),自然找不到对应文档,从而抛出MissingError。

另外,你的@api.onchange装饰器监听字段有误,product_id.price不是可直接监听的字段,应该监听product_id本身。

解决方案

1. 重写product_id_change方法,覆盖原生逻辑

在自定义的SaleOrderLine类中重写该方法,适配product.custom模型,避免原生逻辑报错:

# models/sale_order.py
from openerp import models, fields, api

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    product_id = fields.Many2one(
        'product.custom', string='Product', required=True,
        domain=[('state', 'in', ['confirmed', 'approved'])]
    )

    price_unit = fields.Float(
        string='Price Unit',
        related='product_id.price',  # 从product.custom获取价格
        store=True,
        readonly=True
    )
    
    @api.onchange('product_id')
    def _onchange_product_id(self):
        if not self.product_id:
            return
        self.price_unit = self.product_id.price
        self.name = self.product_id.description
        self.product_uom_qty = self.product_id.qty

    # 重写原生product_id_change方法,适配自定义产品模型
    def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
            uom=False, qty_uos=0, uos=False, name='', partner_id=False,
            lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None):
        res = {'value': {}}
        if product:
            # 用自定义产品模型读取记录
            product_obj = self.pool.get('product.custom').browse(cr, uid, product, context=context)
            # 自定义字段赋值逻辑
            res['value']['name'] = product_obj.description
            res['value']['price_unit'] = product_obj.price
            # 若需要处理税务等其他逻辑,可在此添加适配代码
        return res

2. 修正视图XPath表达式

原生sale.order.form中的product_id字段位于订单行的子视图内,原XPath表达式可能无法精准定位,建议修改为:

<xpath expr="//field[@name='order_line']//field[@name='product_id']" position="replace">
    <field name="product_id"/>
</xpath>

3. 调整onchange监听字段

将@api.onchange('product_id.price','price_unit')改为@api.onchange('product_id'),只有当产品本身变更时才触发逻辑,避免无效监听。

内容的提问来源于stack exchange,提问作者Ananda Rauf Maududi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:08:12