何时、为何以及如何在 Odoo 开发中避免 KeyError
When, why and how to avoid KeyError in Odoo Development
我注意到我开发的一些自定义模块可以安装在有记录的数据库上,而其他模块则抛出 KeyError 消息,除非数据库为空(无记录)。通常当模块包含计算字段时会出现错误。那么,有人知道为什么会这样吗?以及我的代码应该如何避免此类错误?
抛出此错误的示例计算字段如下所示:
from odoo import models, fields, api
from num2words import num2words
Class InheritingAccountMove(models.Model):
_inherit = 'account.move'
total_amount_text = fields.Char(string='Total', compute='_compute_total_amount_text', store=True)
@api.depends('amount_total')
def _compute_total_amount_text(self):
lang_code = self.env.context.get('lang') or self.env.user.lang
language = self.env['res.lang'].search([('iso_code', '=', lang_code)])
separator = language.read()[0]['decimal_point']
for record in self:
decimal_separator = separator
user_language = lang_code[:2]
amount = record.amount_total
amount_list = str(amount).split(decimal_separator)
amount_first_part = num2words(int(amount_list[0]), lang=user_language).title() + ' '
amount_second_part = amount_list[1]
if len(amount_second_part) == 0:
amount_text = amount_first_part + '00/100'
elif len(amount_second_part) < 2:
amount_text = amount_first_part + amount_second_part + '0/100'
else:
amount_text = amount_first_part + amount_second_part[:2] + '/100'
record.total_amount_text = amount_text
已更新
在这种情况下,您的代码出现问题的原因是,当 table(安装时)中没有记录时,您的循环不会 运行,这会导致您的计算字段没有赋值所以
在函数中添加第一行代码
self.total_amount_text = False
这需要为 Odoo 13 和 12 的计算函数中的计算字段赋值
------------------------------------------ ------------------
其他原因可能是:
当试图访问不存在的字典中的键时会发生此错误,例如
language.read()[0]['decimal_point']
字典在安装模块时可能没有 'decimal_point',这可能会返回此错误,处理此问题的常用方法是在访问之前检查密钥是否存在,例如
if 'decimal_point' in language.read()[0].keys()
此外,字典也可以为空,在这种情况下 language.read()[0]
将抛出错误
我更改了我的代码,使其专门针对西班牙语,错误不再出现。我感谢穆罕默德的回答,也许他是对的,但无论如何这是修改后的代码:
@api.depends('invoice_line_ids')
def _compute_total_amount_text(self):
for record in self:
amount = record.amount_total
amount_list = str(amount).split('.')
amount_first_part = num2words(int(amount_list[0]), lang='es').title() + ' '
amount_second_part = amount_list[1]
if len(amount_second_part) == 0:
amount_text = amount_first_part + '00/100'
elif len(amount_second_part) < 2:
amount_text = amount_first_part + amount_second_part + '0/100'
else:
amount_text = amount_first_part + amount_second_part[:2] + '/100'
record.total_amount_text = amount_text
我注意到我开发的一些自定义模块可以安装在有记录的数据库上,而其他模块则抛出 KeyError 消息,除非数据库为空(无记录)。通常当模块包含计算字段时会出现错误。那么,有人知道为什么会这样吗?以及我的代码应该如何避免此类错误? 抛出此错误的示例计算字段如下所示:
from odoo import models, fields, api
from num2words import num2words
Class InheritingAccountMove(models.Model):
_inherit = 'account.move'
total_amount_text = fields.Char(string='Total', compute='_compute_total_amount_text', store=True)
@api.depends('amount_total')
def _compute_total_amount_text(self):
lang_code = self.env.context.get('lang') or self.env.user.lang
language = self.env['res.lang'].search([('iso_code', '=', lang_code)])
separator = language.read()[0]['decimal_point']
for record in self:
decimal_separator = separator
user_language = lang_code[:2]
amount = record.amount_total
amount_list = str(amount).split(decimal_separator)
amount_first_part = num2words(int(amount_list[0]), lang=user_language).title() + ' '
amount_second_part = amount_list[1]
if len(amount_second_part) == 0:
amount_text = amount_first_part + '00/100'
elif len(amount_second_part) < 2:
amount_text = amount_first_part + amount_second_part + '0/100'
else:
amount_text = amount_first_part + amount_second_part[:2] + '/100'
record.total_amount_text = amount_text
已更新
在这种情况下,您的代码出现问题的原因是,当 table(安装时)中没有记录时,您的循环不会 运行,这会导致您的计算字段没有赋值所以
在函数中添加第一行代码
self.total_amount_text = False
这需要为 Odoo 13 和 12 的计算函数中的计算字段赋值
------------------------------------------ ------------------
其他原因可能是:
当试图访问不存在的字典中的键时会发生此错误,例如
language.read()[0]['decimal_point']
字典在安装模块时可能没有 'decimal_point',这可能会返回此错误,处理此问题的常用方法是在访问之前检查密钥是否存在,例如
if 'decimal_point' in language.read()[0].keys()
此外,字典也可以为空,在这种情况下 language.read()[0]
将抛出错误
我更改了我的代码,使其专门针对西班牙语,错误不再出现。我感谢穆罕默德的回答,也许他是对的,但无论如何这是修改后的代码:
@api.depends('invoice_line_ids')
def _compute_total_amount_text(self):
for record in self:
amount = record.amount_total
amount_list = str(amount).split('.')
amount_first_part = num2words(int(amount_list[0]), lang='es').title() + ' '
amount_second_part = amount_list[1]
if len(amount_second_part) == 0:
amount_text = amount_first_part + '00/100'
elif len(amount_second_part) < 2:
amount_text = amount_first_part + amount_second_part + '0/100'
else:
amount_text = amount_first_part + amount_second_part[:2] + '/100'
record.total_amount_text = amount_text