Odoo 12中account.invoice模块client_order_ref字段不存在错误求助
Odoo 12:account.invoice新增计算字段提示不存在问题排查
问题描述
在Odoo 12中继承account.invoice模块,新增计算字段client_order_ref用于从关联销售订单获取对应字段值,但升级模块时系统提示该字段不存在。
相关代码
Python模型代码
from odoo import models, fields, api, _ class AccountInvoice(models.Model): _inherit = 'account.invoice' client_order_ref = fields.Char(string="Client Order Ref", compute="get_client_from_sale_order") @api.depends('name') def get_client_from_sale_order(self): self.ensure_one() for rec in self: sale_order = self.env['sale.order'].search( [('name', '=', rec.origin)] ) rec.client_order_ref = sale_order.client_order_ref
XML视图代码
<?xml version="1.0" encoding="utf-8"?> <odoo> <record id="invoice_tree" model="ir.ui.view"> <field name="name">account_invoice_tree_inherit</field> <field name="model">account.invoice</field> <field name="inherit_id" ref="account.invoice_tree"/> <field name="arch" type="xml"> <xpath expr="//field[@name='partner_id']" position="after"> <field name="client_order_ref"/> </xpath> </field> </record> </odoo>
报错回溯
错误:Odoo服务器错误 Traceback(最近的调用最后): 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第1128行,在 _validate_fields中 check(self) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第351行,在 _check_xml中 self.postprocess_and_fields(view.model, view_doc, view.id) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第1138行,在 postprocess_and_fields中 self.raise_view_error(message, view_id) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第568行,在 raise_view_error中 raise ValueError(message) ValueError: 字段 `client_order_ref` 不存在 错误上下文:视图 `account_invoice_tree_inherit` [view_id: 1311, xml_id: cloudpiles_custom.invoice_tree, model: account.invoice, parent_id: 681] 在处理上述异常期间,发生了另一个异常: Traceback(最近的调用最后): 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第758行,在 parse中 self._tags[rec.tag](rec, de, mode=mode) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第663行,在 _tag_record中 record = model.with_context(rec_context)._load_records([data], self.mode == 'update') 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3883行,在 _load_records中 data['record']._load_records_write(data['values']) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第1542行,在 _load_records_write中 super(View, self)._load_records_write(values) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3821行,在 _load_records_write中 self.write(values) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第445行,在 write中 res = super(View, self).write(self._compute_defaults(vals)) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3392行,在 write中 fields[0].determine_inverse(records) 文件 "/opt/odoo/custom/src/odoo/odoo/fields.py",第1200行,在 determine_inverse中 getattr(records, self.inverse)() 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第275行,在 _inverse_arch中 view.write(data) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第445行,在 write中 res = super(View, self).write(self._compute_defaults(vals)) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3366行,在 write中 self._write(store_vals) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3502行,在 _write中 self._validate_fields(vals) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第1132行,在 _validate_fields中 raise ValidationError("%s\n\n%s" % (_("Error while validating constraint"), tools.ustr(e))) odoo.exceptions.ValidationError: ('验证约束时出错\n\n字段 `client_order_ref` 不存在\n\n错误上下文:\n视图 `account_invoice_tree_inherit`\n[view_id: 1311, xml_id: cloudpiles_custom.invoice_tree, model: account.invoice, parent_id: 681]', None) 在处理上述异常期间,发生了另一个异常: Traceback(最近的调用最后): 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第656行,在 _handle_exception中 return super(JsonRequest, self)._handle_exception(exception) 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第314行,在 _handle_exception中 raise pycompat.reraise(type(exception), exception, sys.exc_info()[2]) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/pycompat.py",第87行,在 reraise中 raise value 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第698行,在 dispatch中 result = self._call_function(**self.params) 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第346行,在 _call_function中 return checked_call(self.db, *args, **kwargs) 文件 "/opt/odoo/custom/src/odoo/odoo/service/model.py",第98行,在 wrapper中 return f(dbname, *args, **kwargs) 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第339行,在 checked_call中 result = self.endpoint(*a, **kw) 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第941行,在 __call__中 return self.method(*args, **kw) 文件 "/opt/odoo/custom/src/odoo/odoo/http.py",第519行,在 response_wrap中 response = f(*args, **kw) 文件 "/opt/odoo/auto/addons/web/controllers/main.py",第967行,在 call_button中 action = self._call_kw(model, method, args, {}) 文件 "/opt/odoo/auto/addons/web/controllers/main.py",第955行,在 _call_kw中 return call_kw(request.env[model], method, args, kwargs) 文件 "/opt/odoo/custom/src/odoo/odoo/api.py",第759行,在 call_kw中 return _call_kw_multi(method, model, args, kwargs) 文件 "/opt/odoo/custom/src/odoo/odoo/api.py",第746行,在 _call_kw_multi中 result = method(recs, *args, **kwargs) 文件 "",第2行,在 button_immediate_upgrade中 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_module.py",第 75行,在 check_and_log中 return method(self, *args, **kwargs) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_module.py",第 628行,在 button_immediate_upgrade中 return self._button_immediate_function(type(self).button_upgrade) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_module.py", 第562行,在 _button_immediate_function中 modules.registry.Registry.new(self._cr.dbname, update_module=True) 文件 "/opt/odoo/custom/src/odoo/odoo/modules/registry.py",第86行,在 new中 odoo.modules.load_modules(registry._db, force_demo, status, update_module) 文件 "/opt/odoo/custom/src/odoo/odoo/modules/loading.py",第417行,在 load_modules中 force, status, report, loaded_modules, update_module, models_to_check) 文件 "/opt/odoo/custom/src/odoo/odoo/modules/loading.py",第313行,在 load_marked_modules中 perform_checks=perform_checks, models_to_check=models_to_check) 文件 "/opt/odoo/custom/src/odoo/odoo/modules/loading.py",第222行,在 load_module_graph中 load_data(cr, idref, mode, kind='data', package=package, report=report) 文件 "/opt/odoo/custom/src/odoo/odoo/modules/loading.py",第68行,在 load_data中 tools.convert_file(cr, package.name, filename, idref, mode, noupdate, kind, report) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第802行,在 convert_file中 convert_xml_import(cr, module, fp, idref, mode, noupdate, report) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第865行,在 convert_xml_import中 obj.parse(doc.getroot(), mode=mode) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第764行,在 parse中 exc_info[2] 文件 "/opt/odoo/custom/src/odoo/odoo/tools/pycompat.py",第86行,在 reraise中 raise value.with_traceback(tb) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第758行,在 parse中 self._tags[rec.tag](rec, de, mode=mode) 文件 "/opt/odoo/custom/src/odoo/odoo/tools/convert.py",第663行,在 _tag_record中 record = model.with_context(rec_context)._load_records([data], self.mode == 'update') 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3883行,在 _load_records中 data['record']._load_records_write(data['values']) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第1542行,在 _load_records_write中 super(View, self)._load_records_write(values) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3821行,在 _load_records_write中 self.write(values) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第445行,在 write中 res = super(View, self).write(self._compute_defaults(vals)) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3392行,在 write中 fields[0].determine_inverse(records) 文件 "/opt/odoo/custom/src/odoo/odoo/fields.py",第1200行,在 determine_inverse中 getattr(records, self.inverse)() 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第275行,在 _inverse_arch中 view.write(data) 文件 "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_ui_view.py", 第445行,在 write中 res = super(View, self).write(self._compute_defaults(vals)) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3366行,在 write中 self._write(store_vals) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第3502行,在 _write中 self._validate_fields(vals) 文件 "/opt/odoo/custom/src/odoo/odoo/models.py",第1132行,在 _validate_fields中 raise ValidationError("%s\n\n%s" % (_("Error while validating constraint"), tools.ustr(e))) odoo.tools.convert.ParseError: "验证约束时出错 字段 `client_order_ref` 不存在 错误上下文:视图 `account_invoice_tree_inherit` [view_id: 1311, xml_id: cloudpiles_custom.invoice_tree, model: account.invoice, parent_id: 681] None" 在解析 /opt/odoo/auto/addons/cloudpiles_custom/views/account_invoice_view.xml:3时, 靠近 account_invoice_tree_inherit account.invoice
问题排查与解决方案
1. 模块依赖与加载顺序问题
报错核心原因是视图加载时模型字段未被正确识别,优先检查模块的__manifest__.py配置:
- 确保模块依赖包含
sale模块,因为代码中引用了sale.order模型,添加:'depends': ['account', 'sale'], - 确认
data列表中视图文件的加载顺序(Odoo会优先加载models目录下的文件,通常无需调整,但需确保视图文件被正确配置)。
2. 计算字段代码修正
原Python代码存在三处关键错误:
self.ensure_one():在循环记录集self前调用该方法会导致多记录场景(如树视图加载)抛出异常,需移除。@api.depends('name'):字段值依赖的是origin字段(关联销售订单号),而非name(发票号),需修改依赖项。- 优化
search方法:添加limit=1提升查询效率,避免返回多条记录;处理未找到销售订单的情况,设置默认空值。
修正后的Python代码:
from odoo import models, fields, api, _ class AccountInvoice(models.Model): _inherit = 'account.invoice' client_order_ref = fields.Char(string="Client Order Ref", compute="get_client_from_sale_order") @api.depends('origin') def get_client_from_sale_order(self): for rec in self: sale_order = self.env['sale.order'].search( [('name', '=', rec.origin)], limit=1 ) rec.client_order_ref = sale_order.client_order_ref or ''
3. 重新升级模块
完成上述修改后,重启Odoo服务,然后重新升级自定义模块,即可解决字段不存在的报错。
内容的提问来源于stack exchange,提问作者odoo newbie
相关产品推荐
相关产品推荐

